github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/puppeth/wizard_node.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package main
    13  
    14  import (
    15  	"encoding/json"
    16  	"fmt"
    17  	"time"
    18  
    19  	"github.com/Sberex/go-sberex/accounts/keystore"
    20  	"github.com/Sberex/go-sberex/common"
    21  	"github.com/Sberex/go-sberex/log"
    22  )
    23  
    24  // deployNode creates a new node configuration based on some user input.
    25  func (w *wizard) deployNode(boot bool) {
    26  	// Do some sanity check before the user wastes time on input
    27  	if w.conf.Genesis == nil {
    28  		log.Error("No genesis block configured")
    29  		return
    30  	}
    31  	if w.conf.ethstats == "" {
    32  		log.Error("No ethstats server configured")
    33  		return
    34  	}
    35  	// Select the server to interact with
    36  	server := w.selectServer()
    37  	if server == "" {
    38  		return
    39  	}
    40  	client := w.servers[server]
    41  
    42  	// Retrieve any active node configurations from the server
    43  	infos, err := checkNode(client, w.network, boot)
    44  	if err != nil {
    45  		if boot {
    46  			infos = &nodeInfos{port: 30303, peersTotal: 512, peersLight: 256}
    47  		} else {
    48  			infos = &nodeInfos{port: 30303, peersTotal: 50, peersLight: 0, gasTarget: 4.7, gasPrice: 18}
    49  		}
    50  	}
    51  	existed := err == nil
    52  
    53  	infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", "  ")
    54  	infos.network = w.conf.Genesis.Config.ChainId.Int64()
    55  
    56  	// Figure out where the user wants to store the persistent data
    57  	fmt.Println()
    58  	if infos.datadir == "" {
    59  		fmt.Printf("Where should data be stored on the remote machine?\n")
    60  		infos.datadir = w.readString()
    61  	} else {
    62  		fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
    63  		infos.datadir = w.readDefaultString(infos.datadir)
    64  	}
    65  	if w.conf.Genesis.Config.Ethash != nil && !boot {
    66  		fmt.Println()
    67  		if infos.ethashdir == "" {
    68  			fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine?\n")
    69  			infos.ethashdir = w.readString()
    70  		} else {
    71  			fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine? (default = %s)\n", infos.ethashdir)
    72  			infos.ethashdir = w.readDefaultString(infos.ethashdir)
    73  		}
    74  	}
    75  	// Figure out which port to listen on
    76  	fmt.Println()
    77  	fmt.Printf("Which TCP/UDP port to listen on? (default = %d)\n", infos.port)
    78  	infos.port = w.readDefaultInt(infos.port)
    79  
    80  	// Figure out how many peers to allow (different based on node type)
    81  	fmt.Println()
    82  	fmt.Printf("How many peers to allow connecting? (default = %d)\n", infos.peersTotal)
    83  	infos.peersTotal = w.readDefaultInt(infos.peersTotal)
    84  
    85  	// Figure out how many light peers to allow (different based on node type)
    86  	fmt.Println()
    87  	fmt.Printf("How many light peers to allow connecting? (default = %d)\n", infos.peersLight)
    88  	infos.peersLight = w.readDefaultInt(infos.peersLight)
    89  
    90  	// Set a proper name to report on the stats page
    91  	fmt.Println()
    92  	if infos.ethstats == "" {
    93  		fmt.Printf("What should the node be called on the stats page?\n")
    94  		infos.ethstats = w.readString() + ":" + w.conf.ethstats
    95  	} else {
    96  		fmt.Printf("What should the node be called on the stats page? (default = %s)\n", infos.ethstats)
    97  		infos.ethstats = w.readDefaultString(infos.ethstats) + ":" + w.conf.ethstats
    98  	}
    99  	// If the node is a miner/signer, load up needed credentials
   100  	if !boot {
   101  		if w.conf.Genesis.Config.Ethash != nil {
   102  			// Ethash based miners only need an etherbase to mine against
   103  			fmt.Println()
   104  			if infos.etherbase == "" {
   105  				fmt.Printf("What address should the miner user?\n")
   106  				for {
   107  					if address := w.readAddress(); address != nil {
   108  						infos.etherbase = address.Hex()
   109  						break
   110  					}
   111  				}
   112  			} else {
   113  				fmt.Printf("What address should the miner user? (default = %s)\n", infos.etherbase)
   114  				infos.etherbase = w.readDefaultAddress(common.HexToAddress(infos.etherbase)).Hex()
   115  			}
   116  		} else if w.conf.Genesis.Config.Clique != nil {
   117  			// If a previous signer was already set, offer to reuse it
   118  			if infos.keyJSON != "" {
   119  				if key, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {
   120  					infos.keyJSON, infos.keyPass = "", ""
   121  				} else {
   122  					fmt.Println()
   123  					fmt.Printf("Reuse previous (%s) signing account (y/n)? (default = yes)\n", key.Address.Hex())
   124  					if w.readDefaultString("y") != "y" {
   125  						infos.keyJSON, infos.keyPass = "", ""
   126  					}
   127  				}
   128  			}
   129  			// Clique based signers need a keyfile and unlock password, ask if unavailable
   130  			if infos.keyJSON == "" {
   131  				fmt.Println()
   132  				fmt.Println("Please paste the signer's key JSON:")
   133  				infos.keyJSON = w.readJSON()
   134  
   135  				fmt.Println()
   136  				fmt.Println("What's the unlock password for the account? (won't be echoed)")
   137  				infos.keyPass = w.readPassword()
   138  
   139  				if _, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {
   140  					log.Error("Failed to decrypt key with given passphrase")
   141  					return
   142  				}
   143  			}
   144  		}
   145  		// Establish the gas dynamics to be enforced by the signer
   146  		fmt.Println()
   147  		fmt.Printf("What gas limit should empty blocks target (MGas)? (default = %0.3f)\n", infos.gasTarget)
   148  		infos.gasTarget = w.readDefaultFloat(infos.gasTarget)
   149  
   150  		fmt.Println()
   151  		fmt.Printf("What gas price should the signer require (GWei)? (default = %0.3f)\n", infos.gasPrice)
   152  		infos.gasPrice = w.readDefaultFloat(infos.gasPrice)
   153  	}
   154  	// Try to deploy the full node on the host
   155  	nocache := false
   156  	if existed {
   157  		fmt.Println()
   158  		fmt.Printf("Should the node be built from scratch (y/n)? (default = no)\n")
   159  		nocache = w.readDefaultString("n") != "n"
   160  	}
   161  	if out, err := deployNode(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
   162  		log.Error("Failed to deploy Sberex node container", "err", err)
   163  		if len(out) > 0 {
   164  			fmt.Printf("%s\n", out)
   165  		}
   166  		return
   167  	}
   168  	// All ok, run a network scan to pick any changes up
   169  	log.Info("Waiting for node to finish booting")
   170  	time.Sleep(3 * time.Second)
   171  
   172  	w.networkStats()
   173  }