From ef7b9fb7d0cbcc2e381074f6be82e4791c41bdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Sat, 13 May 2017 03:03:56 +0300 Subject: cmd/puppeth: v4/v5 boot separation, signer gas configs (#14453) --- cmd/puppeth/module_node.go | 25 ++++++++++++++++++++----- cmd/puppeth/wizard.go | 42 ++++++++++++++++++++++++++++++++++++++++++ cmd/puppeth/wizard_netstats.go | 2 +- cmd/puppeth/wizard_node.go | 12 ++++++++++-- 4 files changed, 73 insertions(+), 8 deletions(-) (limited to 'cmd') diff --git a/cmd/puppeth/module_node.go b/cmd/puppeth/module_node.go index 78681934d..6372f60d2 100644 --- a/cmd/puppeth/module_node.go +++ b/cmd/puppeth/module_node.go @@ -40,7 +40,7 @@ ADD genesis.json /genesis.json RUN \ echo '/geth init /genesis.json' > geth.sh && \{{if .Unlock}} echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}} - echo $'/geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .Bootnodes}}--bootnodes {{.Bootnodes}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine{{end}}{{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}}' >> geth.sh + echo $'/geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .BootV4}}--bootnodesv4 {{.BootV4}}{{end}} {{if .BootV5}}--bootnodesv5 {{.BootV5}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine{{end}}{{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --targetgaslimit {{.GasTarget}} --gasprice {{.GasPrice}}' >> geth.sh ENTRYPOINT ["/bin/sh", "geth.sh"] ` @@ -66,17 +66,20 @@ services: - LIGHT_PEERS={{.LightPeers}} - STATS_NAME={{.Ethstats}} - MINER_NAME={{.Etherbase}} + - GAS_TARGET={{.GasTarget}} + - GAS_PRICE={{.GasPrice}} restart: always ` // deployNode deploys a new Ethereum node container to a remote machine via SSH, // docker and docker-compose. If an instance with the specified network name // already exists there, it will be overwritten! -func deployNode(client *sshClient, network string, bootnodes []string, config *nodeInfos) ([]byte, error) { +func deployNode(client *sshClient, network string, bootv4, bootv5 []string, config *nodeInfos) ([]byte, error) { kind := "sealnode" if config.keyJSON == "" && config.etherbase == "" { kind = "bootnode" - bootnodes = make([]string, 0) + bootv4 = make([]string, 0) + bootv5 = make([]string, 0) } // Generate the content to upload to the server workdir := fmt.Sprintf("%d", rand.Int63()) @@ -92,9 +95,12 @@ func deployNode(client *sshClient, network string, bootnodes []string, config *n "Port": config.portFull, "Peers": config.peersTotal, "LightFlag": lightFlag, - "Bootnodes": strings.Join(bootnodes, ","), + "BootV4": strings.Join(bootv4, ","), + "BootV5": strings.Join(bootv5, ","), "Ethstats": config.ethstats, "Etherbase": config.etherbase, + "GasTarget": uint64(1000000 * config.gasTarget), + "GasPrice": uint64(1000000000 * config.gasPrice), "Unlock": config.keyJSON != "", }) files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes() @@ -111,6 +117,8 @@ func deployNode(client *sshClient, network string, bootnodes []string, config *n "LightPeers": config.peersLight, "Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")], "Etherbase": config.etherbase, + "GasTarget": config.gasTarget, + "GasPrice": config.gasPrice, }) files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes() @@ -147,6 +155,8 @@ type nodeInfos struct { etherbase string keyJSON string keyPass string + gasTarget float64 + gasPrice float64 } // String implements the stringer interface. @@ -155,7 +165,8 @@ func (info *nodeInfos) String() string { if info.peersLight > 0 { discv5 = fmt.Sprintf(", portv5=%d", info.portLight) } - return fmt.Sprintf("port=%d%s, datadir=%s, peers=%d, lights=%d, ethstats=%s", info.portFull, discv5, info.datadir, info.peersTotal, info.peersLight, info.ethstats) + return fmt.Sprintf("port=%d%s, datadir=%s, peers=%d, lights=%d, ethstats=%s, gastarget=%0.3f MGas, gasprice=%0.3f GWei", + info.portFull, discv5, info.datadir, info.peersTotal, info.peersLight, info.ethstats, info.gasTarget, info.gasPrice) } // checkNode does a health-check against an boot or seal node server to verify @@ -176,6 +187,8 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) // Resolve a few types from the environmental variables totalPeers, _ := strconv.Atoi(infos.envvars["TOTAL_PEERS"]) lightPeers, _ := strconv.Atoi(infos.envvars["LIGHT_PEERS"]) + gasTarget, _ := strconv.ParseFloat(infos.envvars["GAS_TARGET"], 64) + gasPrice, _ := strconv.ParseFloat(infos.envvars["GAS_PRICE"], 64) // Container available, retrieve its node ID and its genesis json var out []byte @@ -213,6 +226,8 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) etherbase: infos.envvars["MINER_NAME"], keyJSON: keyJSON, keyPass: keyPass, + gasTarget: gasTarget, + gasPrice: gasPrice, } stats.enodeFull = fmt.Sprintf("enode://%s@%s:%d", id, client.address, stats.portFull) if stats.portLight != 0 { diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go index 9687d5e0d..51e64688e 100644 --- a/cmd/puppeth/wizard.go +++ b/cmd/puppeth/wizard.go @@ -162,6 +162,48 @@ func (w *wizard) readDefaultInt(def int) int { } } +// readFloat reads a single line from stdin, trimming if from spaces, enforcing it +// to parse into a float. +func (w *wizard) readFloat() float64 { + for { + fmt.Printf("> ") + text, err := w.in.ReadString('\n') + if err != nil { + log.Crit("Failed to read user input", "err", err) + } + if text = strings.TrimSpace(text); text == "" { + continue + } + val, err := strconv.ParseFloat(strings.TrimSpace(text), 64) + if err != nil { + log.Error("Invalid input, expected float", "err", err) + continue + } + return val + } +} + +// readDefaultFloat reads a single line from stdin, trimming if from spaces, enforcing +// it to parse into a float. If an empty line is entered, the default value is returned. +func (w *wizard) readDefaultFloat(def float64) float64 { + for { + fmt.Printf("> ") + text, err := w.in.ReadString('\n') + if err != nil { + log.Crit("Failed to read user input", "err", err) + } + if text = strings.TrimSpace(text); text == "" { + return def + } + val, err := strconv.ParseFloat(strings.TrimSpace(text), 64) + if err != nil { + log.Error("Invalid input, expected float", "err", err) + continue + } + return val + } +} + // readPassword reads a single line from stdin, trimming it from the trailing new // line and returns it. The input will not be echoed. func (w *wizard) readPassword() string { diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go index 1225abb75..ab8078698 100644 --- a/cmd/puppeth/wizard_netstats.go +++ b/cmd/puppeth/wizard_netstats.go @@ -39,7 +39,7 @@ func (w *wizard) networkStats(tips bool) { // Iterate over all the specified hosts and check their status stats := tablewriter.NewWriter(os.Stdout) stats.SetHeader([]string{"Server", "IP", "Status", "Service", "Details"}) - stats.SetColWidth(128) + stats.SetColWidth(100) for server, pubkey := range w.conf.Servers { client := w.servers[server] diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go index d70d8f3c9..483d9fe05 100644 --- a/cmd/puppeth/wizard_node.go +++ b/cmd/puppeth/wizard_node.go @@ -50,7 +50,7 @@ func (w *wizard) deployNode(boot bool) { if boot { infos = &nodeInfos{portFull: 30303, peersTotal: 512, peersLight: 256} } else { - infos = &nodeInfos{portFull: 30303, peersTotal: 50, peersLight: 0} + infos = &nodeInfos{portFull: 30303, peersTotal: 50, peersLight: 0, gasTarget: 4.7, gasPrice: 18} } } infos.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") @@ -136,9 +136,17 @@ func (w *wizard) deployNode(boot bool) { } } } + // Establish the gas dynamics to be enforced by the signer + fmt.Println() + fmt.Printf("What gas limit should empty blocks target (MGas)? (default = %0.3f)\n", infos.gasTarget) + infos.gasTarget = w.readDefaultFloat(infos.gasTarget) + + fmt.Println() + fmt.Printf("What gas price should the signer require (GWei)? (default = %0.3f)\n", infos.gasPrice) + infos.gasPrice = w.readDefaultFloat(infos.gasPrice) } // Try to deploy the full node on the host - if out, err := deployNode(client, w.network, w.conf.bootFull, infos); err != nil { + if out, err := deployNode(client, w.network, w.conf.bootFull, w.conf.bootLight, infos); err != nil { log.Error("Failed to deploy Ethereum node container", "err", err) if len(out) > 0 { fmt.Printf("%s\n", out) -- cgit v1.2.3