cmd/utils: add BigFlag and use it for error-checked integer flags

While here, remove environment variable processing for DirectoryFlag
because we don't use it.
This commit is contained in:
Felix Lange 2017-02-22 13:36:02 +01:00
parent d3114f5e3b
commit f2c65943d7
2 changed files with 75 additions and 35 deletions

View file

@ -17,12 +17,17 @@
package utils package utils
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"math/big"
"os" "os"
"os/user" "os/user"
"path" "path"
"strings" "strings"
"github.com/ethereum/go-ethereum/common/math"
"gopkg.in/urfave/cli.v1"
) )
// Custom type which is registered in the flags library which cli uses for // Custom type which is registered in the flags library which cli uses for
@ -44,10 +49,9 @@ func (self *DirectoryString) Set(value string) error {
// Custom cli.Flag type which expand the received string to an absolute path. // Custom cli.Flag type which expand the received string to an absolute path.
// e.g. ~/.ethereum -> /home/username/.ethereum // e.g. ~/.ethereum -> /home/username/.ethereum
type DirectoryFlag struct { type DirectoryFlag struct {
Name string Name string
Value DirectoryString Value DirectoryString
Usage string Usage string
EnvVar string
} }
func (self DirectoryFlag) String() string { func (self DirectoryFlag) String() string {
@ -55,7 +59,7 @@ func (self DirectoryFlag) String() string {
if len(self.Value.Value) > 0 { if len(self.Value.Value) > 0 {
fmtString = "%s \"%v\"\t%v" fmtString = "%s \"%v\"\t%v"
} }
return withEnvHint(self.EnvVar, fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage)) return fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage)
} }
func eachName(longName string, fn func(string)) { func eachName(longName string, fn func(string)) {
@ -69,21 +73,65 @@ func eachName(longName string, fn func(string)) {
// called by cli library, grabs variable from environment (if in env) // called by cli library, grabs variable from environment (if in env)
// and adds variable to flag set for parsing. // and adds variable to flag set for parsing.
func (self DirectoryFlag) Apply(set *flag.FlagSet) { func (self DirectoryFlag) Apply(set *flag.FlagSet) {
if self.EnvVar != "" {
for _, envVar := range strings.Split(self.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
self.Value.Value = envVal
break
}
}
}
eachName(self.Name, func(name string) { eachName(self.Name, func(name string) {
set.Var(&self.Value, self.Name, self.Usage) set.Var(&self.Value, self.Name, self.Usage)
}) })
} }
// BigFlag is a command line flag that accepts big integers in decimal
// or hexadecimal syntax.
type BigFlag struct {
Name string
Value *big.Int
Usage string
}
// bigValue turns *big.Int into a flag.Value
type bigValue big.Int
func (b *bigValue) String() string {
if b == nil {
return ""
}
return (*big.Int)(b).String()
}
func (b *bigValue) Set(s string) error {
int, ok := math.ParseBig(s)
if !ok {
return errors.New("invalid integer syntax")
}
*b = (bigValue)(*int)
return nil
}
func (f BigFlag) GetName() string {
return f.Name
}
func (f BigFlag) String() string {
fmtString := "%s %v\t%v"
if f.Value != nil {
fmtString = "%s \"%v\"\t%v"
}
return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)
}
func (f BigFlag) Apply(set *flag.FlagSet) {
eachName(f.Name, func(name string) {
set.Var((*bigValue)(f.Value), f.Name, f.Usage)
})
}
// GlobalBig returns the value of a BigFlag from the global flag set.
func GlobalBig(ctx *cli.Context, name string) *big.Int {
val := ctx.GlobalGeneric(name)
if val == nil {
return nil
}
return (*big.Int)(val.(*bigValue))
}
func prefixFor(name string) (prefix string) { func prefixFor(name string) (prefix string) {
if len(name) == 1 { if len(name) == 1 {
prefix = "-" prefix = "-"
@ -106,14 +154,6 @@ func prefixedNames(fullName string) (prefixed string) {
return return
} }
func withEnvHint(envVar, str string) string {
envText := ""
if envVar != "" {
envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $"))
}
return str + envText
}
func (self DirectoryFlag) GetName() string { func (self DirectoryFlag) GetName() string {
return self.Name return self.Name
} }

View file

@ -179,10 +179,10 @@ var (
Usage: "Number of CPU threads to use for mining", Usage: "Number of CPU threads to use for mining",
Value: runtime.NumCPU(), Value: runtime.NumCPU(),
} }
TargetGasLimitFlag = cli.StringFlag{ TargetGasLimitFlag = cli.Uint64Flag{
Name: "targetgaslimit", Name: "targetgaslimit",
Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine",
Value: params.GenesisGasLimit.String(), Value: params.GenesisGasLimit.Uint64(),
} }
AutoDAGFlag = cli.BoolFlag{ AutoDAGFlag = cli.BoolFlag{
Name: "autodag", Name: "autodag",
@ -193,10 +193,10 @@ var (
Usage: "Public address for block mining rewards (default = first account created)", Usage: "Public address for block mining rewards (default = first account created)",
Value: "0", Value: "0",
} }
GasPriceFlag = cli.StringFlag{ GasPriceFlag = BigFlag{
Name: "gasprice", Name: "gasprice",
Usage: "Minimal gas price to accept for mining a transactions", Usage: "Minimal gas price to accept for mining a transactions",
Value: fmt.Sprint(uint64(20 * params.Shannon)), Value: big.NewInt(20 * params.Shannon),
} }
ExtraDataFlag = cli.StringFlag{ ExtraDataFlag = cli.StringFlag{
Name: "extradata", Name: "extradata",
@ -382,15 +382,15 @@ var (
} }
// Gas price oracle settings // Gas price oracle settings
GpoMinGasPriceFlag = cli.StringFlag{ GpoMinGasPriceFlag = BigFlag{
Name: "gpomin", Name: "gpomin",
Usage: "Minimum suggested gas price", Usage: "Minimum suggested gas price",
Value: fmt.Sprint(uint64(20 * params.Shannon)), Value: big.NewInt(20 * params.Shannon),
} }
GpoMaxGasPriceFlag = cli.StringFlag{ GpoMaxGasPriceFlag = BigFlag{
Name: "gpomax", Name: "gpomax",
Usage: "Maximum suggested gas price", Usage: "Maximum suggested gas price",
Value: fmt.Sprint(uint64(500 * params.Shannon)), Value: big.NewInt(500 * params.Shannon),
} }
GpoFullBlockRatioFlag = cli.IntFlag{ GpoFullBlockRatioFlag = cli.IntFlag{
Name: "gpofull", Name: "gpofull",
@ -741,9 +741,9 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
ExtraData: MakeMinerExtra(extra, ctx), ExtraData: MakeMinerExtra(extra, ctx),
DocRoot: ctx.GlobalString(DocRootFlag.Name), DocRoot: ctx.GlobalString(DocRootFlag.Name),
GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)), GasPrice: GlobalBig(ctx, GasPriceFlag.Name),
GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)), GpoMinGasPrice: GlobalBig(ctx, GpoMinGasPriceFlag.Name),
GpoMaxGasPrice: common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)), GpoMaxGasPrice: GlobalBig(ctx, GpoMaxGasPriceFlag.Name),
GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name), GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name),
GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name), GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name),
GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name), GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name),
@ -819,7 +819,7 @@ func RegisterEthStatsService(stack *node.Node, url string) {
// SetupNetwork configures the system for either the main net or some test network. // SetupNetwork configures the system for either the main net or some test network.
func SetupNetwork(ctx *cli.Context) { func SetupNetwork(ctx *cli.Context) {
params.TargetGasLimit = common.String2Big(ctx.GlobalString(TargetGasLimitFlag.Name)) params.TargetGasLimit = new(big.Int).SetUint64(ctx.GlobalUint64(TargetGasLimitFlag.Name))
} }
// MakeChainConfig reads the chain configuration from the database in ctx.Datadir. // MakeChainConfig reads the chain configuration from the database in ctx.Datadir.