cli: implement Fixed8Flag

Parsing gas from float value is not always a right idea as
a transform from float is not 1-to-1.
This commit implements Fixed8Flag which parses Fixed8 value from string.
This commit is contained in:
Evgenii Stratonikov 2020-03-12 19:41:54 +03:00
parent d129c5c47b
commit ca476cbf8a
3 changed files with 80 additions and 12 deletions

75
cli/flags/fixed8.go Normal file
View file

@ -0,0 +1,75 @@
package flags
import (
"flag"
"strings"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/urfave/cli"
)
// Fixed8 is a wrapper for Uint160 with flag.Value methods.
type Fixed8 struct {
Value util.Fixed8
}
// Fixed8Flag is a flag with type string.
type Fixed8Flag struct {
Name string
Usage string
Value Fixed8
}
var (
_ flag.Value = (*Fixed8)(nil)
_ cli.Flag = Fixed8Flag{}
)
// String implements fmt.Stringer interface.
func (a Fixed8) String() string {
return a.Value.String()
}
// Set implements flag.Value interface.
func (a *Fixed8) Set(s string) error {
f, err := util.Fixed8FromString(s)
if err != nil {
return cli.NewExitError(err, 1)
}
a.Value = f
return nil
}
// Fixed8 casts address to util.Fixed8.
func (a *Fixed8) Fixed8() util.Fixed8 {
return a.Value
}
// String returns a readable representation of this value
// (for usage defaults).
func (f Fixed8Flag) String() string {
var names []string
eachName(f.Name, func(name string) {
names = append(names, getNameHelp(name))
})
return strings.Join(names, ", ") + "\t" + f.Usage
}
// GetName returns the name of the flag.
func (f Fixed8Flag) GetName() string {
return f.Name
}
// Apply populates the flag given the flag set and environment
// Ignores errors.
func (f Fixed8Flag) Apply(set *flag.FlagSet) {
eachName(f.Name, func(name string) {
set.Var(&f.Value, name, f.Usage)
})
}
// Fixed8FromContext returns parsed util.Fixed8 value provided flag name.
func Fixed8FromContext(ctx *cli.Context, name string) util.Fixed8 {
return ctx.Generic(name).(*Fixed8Flag).Value.Fixed8()
}

View file

@ -51,7 +51,7 @@ var (
Name: "address, a", Name: "address, a",
Usage: "address to use as transaction signee (and gas source)", Usage: "address to use as transaction signee (and gas source)",
} }
gasFlag = cli.Float64Flag{ gasFlag = flags.Fixed8Flag{
Name: "gas, g", Name: "gas, g",
Usage: "gas to add to the transaction", Usage: "gas to add to the transaction",
} }
@ -411,7 +411,7 @@ func invokeInternal(ctx *cli.Context, withMethod bool, signAndPush bool) error {
} }
if signAndPush { if signAndPush {
gas = util.Fixed8FromFloat(ctx.Float64("gas")) gas = flags.Fixed8FromContext(ctx, "gas")
acc, err = getAccFromContext(ctx) acc, err = getAccFromContext(ctx)
if err != nil { if err != nil {
return err return err
@ -593,7 +593,7 @@ func contractDeploy(ctx *cli.Context) error {
if len(endpoint) == 0 { if len(endpoint) == 0 {
return cli.NewExitError(errNoEndpoint, 1) return cli.NewExitError(errNoEndpoint, 1)
} }
gas := util.Fixed8FromFloat(ctx.Float64("gas")) gas := flags.Fixed8FromContext(ctx, "gas")
acc, err := getAccFromContext(ctx) acc, err := getAccFromContext(ctx)
if err != nil { if err != nil {

View file

@ -85,7 +85,7 @@ func newNEP5Commands() []cli.Command {
Name: "amount", Name: "amount",
Usage: "Amount of asset to send", Usage: "Amount of asset to send",
}, },
cli.StringFlag{ flags.Fixed8Flag{
Name: "gas", Name: "gas",
Usage: "Amount of GAS to attach to a tx", Usage: "Amount of GAS to attach to a tx",
}, },
@ -309,14 +309,7 @@ func transferNEP5(ctx *cli.Context) error {
emit.AppCall(w.BinWriter, token.Hash, false) emit.AppCall(w.BinWriter, token.Hash, false)
emit.Opcode(w.BinWriter, opcode.THROWIFNOT) emit.Opcode(w.BinWriter, opcode.THROWIFNOT)
var gas util.Fixed8 gas := flags.Fixed8FromContext(ctx, "gas")
if gasString := ctx.String("gas"); gasString != "" {
gas, err = util.Fixed8FromString(gasString)
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid GAS amount: %v", err), 1)
}
}
tx := transaction.NewInvocationTX(w.Bytes(), gas) tx := transaction.NewInvocationTX(w.Bytes(), gas)
tx.Attributes = append(tx.Attributes, transaction.Attribute{ tx.Attributes = append(tx.Attributes, transaction.Attribute{
Usage: transaction.Script, Usage: transaction.Script,