forked from TrueCloudLab/neoneo-go
Merge pull request #2180 from nspcc-dev/cli-show-fee
cli/wallet: show tx fee before relaying
This commit is contained in:
commit
d915f085a7
11 changed files with 104 additions and 5 deletions
|
@ -22,6 +22,7 @@ func TestRegisterCandidate(t *testing.T) {
|
|||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:"+validatorPriv.Address()+":10",
|
||||
"GAS:"+validatorPriv.Address()+":10000")
|
||||
e.checkTxPersisted(t)
|
||||
|
|
|
@ -175,6 +175,7 @@ func TestContractDeployWithData(t *testing.T) {
|
|||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet, "--address", validatorAddr,
|
||||
"--in", nefName, "--manifest", manifestName,
|
||||
"--force",
|
||||
"[", "key1", "12", "key2", "take_me_to_church", "]")
|
||||
|
||||
e.checkTxPersisted(t, "Sent invocation transaction ")
|
||||
|
@ -242,6 +243,7 @@ func TestContractManifestGroups(t *testing.T) {
|
|||
e.Run(t, "neo-go", "contract", "deploy",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--in", nefName, "--manifest", manifestName,
|
||||
"--force",
|
||||
"--wallet", validatorWallet, "--address", validatorAddr)
|
||||
}
|
||||
|
||||
|
@ -261,6 +263,7 @@ func deployContract(t *testing.T, e *executor, inPath, configPath, wallet, addre
|
|||
e.Run(t, "neo-go", "contract", "deploy",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", wallet, "--address", address,
|
||||
"--force",
|
||||
"--in", nefName, "--manifest", manifestName)
|
||||
e.checkTxPersisted(t, "Sent invocation transaction ")
|
||||
line, err := e.Out.ReadString('\n')
|
||||
|
@ -297,7 +300,7 @@ func TestComlileAndInvokeFunction(t *testing.T) {
|
|||
|
||||
e.In.WriteString("one\r")
|
||||
e.Run(t, "neo-go", "contract", "deploy",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr, "--force",
|
||||
"--wallet", validatorWallet, "--address", validatorAddr,
|
||||
"--in", nefName, "--manifest", manifestName)
|
||||
|
||||
|
@ -371,11 +374,20 @@ func TestComlileAndInvokeFunction(t *testing.T) {
|
|||
})
|
||||
|
||||
cmd = append(cmd, "--wallet", validatorWallet, "--address", validatorAddr)
|
||||
t.Run("cancelled", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.In.WriteString("n\r")
|
||||
e.RunWithError(t, append(cmd, h.StringLE(), "getValue")...)
|
||||
})
|
||||
t.Run("confirmed", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.In.WriteString("y\r")
|
||||
e.Run(t, append(cmd, h.StringLE(), "getValue")...)
|
||||
})
|
||||
|
||||
t.Run("failind method", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.In.WriteString("y\r")
|
||||
e.RunWithError(t, append(cmd, h.StringLE(), "fail")...)
|
||||
|
||||
e.In.WriteString("one\r")
|
||||
|
@ -384,6 +396,7 @@ func TestComlileAndInvokeFunction(t *testing.T) {
|
|||
|
||||
t.Run("cosigner is deployed contract", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.In.WriteString("y\r")
|
||||
e.Run(t, append(cmd, h.StringLE(), "getValue",
|
||||
"--", validatorAddr, hVerify.StringLE())...)
|
||||
})
|
||||
|
@ -499,6 +512,7 @@ func TestComlileAndInvokeFunction(t *testing.T) {
|
|||
e.Run(t, "neo-go", "contract", "invokefunction",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet, "--address", validatorAddr,
|
||||
"--force",
|
||||
h.StringLE(), "update",
|
||||
"bytes:"+hex.EncodeToString(rawNef),
|
||||
"bytes:"+hex.EncodeToString(rawManifest),
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package input
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
|
@ -55,3 +58,18 @@ func ReadPassword(prompt string) (string, error) {
|
|||
}
|
||||
return trm.ReadPassword(prompt)
|
||||
}
|
||||
|
||||
// ConfirmTx asks for a confirmation to send tx.
|
||||
func ConfirmTx(w io.Writer, tx *transaction.Transaction) error {
|
||||
fmt.Fprintf(w, "Network fee: %d\n", tx.NetworkFee)
|
||||
fmt.Fprintf(w, "System fee: %d\n", tx.SystemFee)
|
||||
fmt.Fprintf(w, "Total fee: %d\n", tx.NetworkFee+tx.SystemFee)
|
||||
ln, err := ReadLine("Relay transaction (y|N)> ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if 0 < len(ln) && ln[0] == 'y' || ln[0] == 'Y' {
|
||||
return nil
|
||||
}
|
||||
return errors.New("cancelled")
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ func TestSignMultisigTx(t *testing.T) {
|
|||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:"+multisigAddr+":4",
|
||||
"GAS:"+multisigAddr+":1")
|
||||
e.checkTxPersisted(t)
|
||||
|
|
|
@ -107,6 +107,7 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
|
|||
"--to", nftOwnerAddr,
|
||||
"--token", "GAS",
|
||||
"--amount", "10000",
|
||||
"--force",
|
||||
"--from", validatorAddr)
|
||||
e.checkTxPersisted(t)
|
||||
|
||||
|
@ -122,6 +123,7 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
|
|||
"--to", h.StringLE(),
|
||||
"--token", "GAS",
|
||||
"--amount", "10",
|
||||
"--force",
|
||||
"--from", nftOwnerAddr)
|
||||
txMint, _ := e.checkTxPersisted(t)
|
||||
|
||||
|
@ -259,6 +261,7 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
|
|||
"--wallet", wall,
|
||||
"--to", validatorAddr,
|
||||
"--from", nftOwnerAddr,
|
||||
"--force",
|
||||
}
|
||||
|
||||
// transfer: unimported token with symbol id specified
|
||||
|
@ -290,6 +293,7 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
|
|||
"--from", nftOwnerAddr,
|
||||
"--token", h.StringLE(),
|
||||
"--id", string(tokenID1),
|
||||
"--force",
|
||||
"string:some_data",
|
||||
}
|
||||
e.In.WriteString(nftOwnerPass + "\r")
|
||||
|
|
|
@ -122,8 +122,23 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
e.In.Reset()
|
||||
})
|
||||
|
||||
t.Run("no confirmation", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.RunWithError(t, args...)
|
||||
e.In.Reset()
|
||||
})
|
||||
t.Run("cancel after prompt", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.RunWithError(t, args...)
|
||||
e.In.Reset()
|
||||
})
|
||||
|
||||
e.In.WriteString("one\r")
|
||||
e.In.WriteString("Y\r")
|
||||
e.Run(t, args...)
|
||||
e.checkNextLine(t, `^Network fee:\s*(\d|\.)+`)
|
||||
e.checkNextLine(t, `^System fee:\s*(\d|\.)+`)
|
||||
e.checkNextLine(t, `^Total fee:\s*(\d|\.)+`)
|
||||
e.checkTxPersisted(t)
|
||||
|
||||
sh, err := address.StringToUint160(w.Accounts[0].Address)
|
||||
|
@ -131,6 +146,17 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
b, _ := e.Chain.GetGoverningTokenBalance(sh)
|
||||
require.Equal(t, big.NewInt(1), b)
|
||||
|
||||
t.Run("with force", func(t *testing.T) {
|
||||
e.In.WriteString("one\r")
|
||||
e.Run(t, append(args, "--force")...)
|
||||
e.checkTxPersisted(t)
|
||||
|
||||
sh, err := address.StringToUint160(w.Accounts[0].Address)
|
||||
require.NoError(t, err)
|
||||
b, _ := e.Chain.GetGoverningTokenBalance(sh)
|
||||
require.Equal(t, big.NewInt(2), b)
|
||||
})
|
||||
|
||||
hVerify := deployVerifyContract(t, e)
|
||||
const validatorDefault = "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"
|
||||
|
||||
|
@ -140,11 +166,13 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:"+validatorDefault+":42",
|
||||
"GAS:"+validatorDefault+":7")
|
||||
e.checkTxPersisted(t)
|
||||
|
||||
args := args[:len(args)-2] // cut '--from' argument
|
||||
args = append(args, "--force")
|
||||
e.In.WriteString("one\r")
|
||||
e.Run(t, args...)
|
||||
e.checkTxPersisted(t)
|
||||
|
@ -152,7 +180,7 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
sh, err := address.StringToUint160(w.Accounts[0].Address)
|
||||
require.NoError(t, err)
|
||||
b, _ := e.Chain.GetGoverningTokenBalance(sh)
|
||||
require.Equal(t, big.NewInt(2), b)
|
||||
require.Equal(t, big.NewInt(3), b)
|
||||
|
||||
sh, err = address.StringToUint160(validatorDefault)
|
||||
require.NoError(t, err)
|
||||
|
@ -166,6 +194,7 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:"+validatorDefault+":42",
|
||||
"GAS:"+validatorDefault+":7",
|
||||
"--", validatorAddr+":Global")
|
||||
|
@ -181,6 +210,7 @@ func TestNEP17Transfer(t *testing.T) {
|
|||
"--token", "GAS",
|
||||
"--amount", "1",
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"[", validatorAddr, strconv.Itoa(int(validTil)), "]"}
|
||||
|
||||
t.Run("with data", func(t *testing.T) {
|
||||
|
@ -218,6 +248,7 @@ func TestNEP17MultiTransfer(t *testing.T) {
|
|||
"--rpc-endpoint", "http://" + e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:" + privs[0].Address() + ":42",
|
||||
"GAS:" + privs[1].Address() + ":7",
|
||||
neoContractHash.StringLE() + ":" + privs[2].Address() + ":13",
|
||||
|
|
|
@ -34,6 +34,7 @@ func TestQueryTx(t *testing.T) {
|
|||
"--to", w.Accounts[0].Address,
|
||||
"--token", "NEO",
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
}
|
||||
|
||||
e.In.WriteString("one\r")
|
||||
|
|
|
@ -660,7 +660,17 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet,
|
|||
if len(resp.Script) == 0 {
|
||||
return sender, cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
|
||||
}
|
||||
txHash, err := c.SignAndPushInvocationTx(resp.Script, acc, resp.GasConsumed+int64(sysgas), gas, cosignersAccounts)
|
||||
tx, err := c.CreateTxFromScript(resp.Script, acc, resp.GasConsumed+int64(sysgas), int64(gas), cosignersAccounts)
|
||||
if err != nil {
|
||||
return sender, cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1)
|
||||
}
|
||||
if !ctx.Bool("force") {
|
||||
err := input.ConfirmTx(ctx.App.Writer, tx)
|
||||
if err != nil {
|
||||
return sender, cli.NewExitError(err, 1)
|
||||
}
|
||||
}
|
||||
txHash, err := c.SignAndPushTx(tx, acc, cosignersAccounts)
|
||||
if err != nil {
|
||||
return sender, cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -262,6 +263,12 @@ func signAndSendNEP11Transfer(ctx *cli.Context, c *client.Client, acc *wallet.Ac
|
|||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
} else {
|
||||
if !ctx.Bool("force") {
|
||||
err := input.ConfirmTx(ctx.App.Writer, tx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
}
|
||||
_, err := c.SignAndPushTx(tx, acc, cosigners)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/cli/options"
|
||||
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
|
@ -55,6 +56,7 @@ var (
|
|||
tokenFlag,
|
||||
gasFlag,
|
||||
sysGasFlag,
|
||||
forceFlag,
|
||||
cli.StringFlag{
|
||||
Name: "amount",
|
||||
Usage: "Amount of asset to send",
|
||||
|
@ -66,6 +68,7 @@ var (
|
|||
fromAddrFlag,
|
||||
gasFlag,
|
||||
sysGasFlag,
|
||||
forceFlag,
|
||||
}, options.RPC...)
|
||||
)
|
||||
|
||||
|
@ -580,6 +583,12 @@ func signAndSendNEP17Transfer(ctx *cli.Context, c *client.Client, acc *wallet.Ac
|
|||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
} else {
|
||||
if !ctx.Bool("force") {
|
||||
err := input.ConfirmTx(ctx.App.Writer, tx)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
}
|
||||
_, err := c.SignAndPushTx(tx, acc, cosigners)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err, 1)
|
||||
|
|
|
@ -222,6 +222,7 @@ func TestClaimGas(t *testing.T) {
|
|||
"--rpc-endpoint", "http://" + e.RPC.Addr,
|
||||
"--wallet", validatorWallet,
|
||||
"--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:" + testWalletAccount + ":1000",
|
||||
"GAS:" + testWalletAccount + ":1000", // for tx send
|
||||
}
|
||||
|
@ -293,6 +294,7 @@ func TestImportDeployed(t *testing.T) {
|
|||
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", validatorWallet, "--from", validatorAddr,
|
||||
"--force",
|
||||
"NEO:"+contractAddr+":10",
|
||||
"GAS:"+contractAddr+":10")
|
||||
e.checkTxPersisted(t)
|
||||
|
@ -304,6 +306,7 @@ func TestImportDeployed(t *testing.T) {
|
|||
e.Run(t, "neo-go", "wallet", "nep17", "transfer",
|
||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||
"--wallet", walletPath, "--from", contractAddr,
|
||||
"--force",
|
||||
"--to", privTo.Address(), "--token", "NEO", "--amount", "1")
|
||||
e.checkTxPersisted(t)
|
||||
|
||||
|
|
Loading…
Reference in a new issue