cmd/puppeth: store genesis locally to persist restarts

This commit is contained in:
Péter Szilágyi 2017-10-26 12:39:03 +03:00
parent 7abf968d6f
commit 80be5e5463
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
9 changed files with 64 additions and 49 deletions

@ -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
}

@ -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"`
}

@ -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

@ -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()

@ -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")
}

@ -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()

@ -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 != "" {

@ -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 {

@ -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()