diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index ef2159dd3..15a5e85cc 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -8,19 +8,17 @@ import ( "os" "path/filepath" "strings" - "time" "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/cli/txctx" cliwallet "github.com/nspcc-dev/neo-go/cli/wallet" "github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" @@ -62,22 +60,6 @@ var ( Name: addressFlagName, Usage: "address to use as transaction signee (and gas source)", } - gasFlag = flags.Fixed8Flag{ - Name: "gas, g", - Usage: "network fee to add to the transaction (prioritizing it)", - } - sysGasFlag = flags.Fixed8Flag{ - Name: "sysgas, e", - Usage: "system fee to add to transaction (compensating for execution)", - } - outFlag = cli.StringFlag{ - Name: "out", - Usage: "file to put JSON transaction to", - } - forceFlag = cli.BoolFlag{ - Name: "force", - Usage: "force-push the transaction in case of bad VM state after test script invocation", - } ) // ModVersion contains `pkg/interop` module version @@ -120,10 +102,10 @@ func NewCommands() []cli.Command { walletFlag, walletConfigFlag, addressFlag, - gasFlag, - sysGasFlag, - outFlag, - forceFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.OutFlag, + txctx.ForceFlag, } invokeFunctionFlags = append(invokeFunctionFlags, options.RPC...) deployFlags := append(invokeFunctionFlags, []cli.Flag{ @@ -668,7 +650,6 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error { func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, script util.Uint160, operation string, params []interface{}, cosigners []transaction.Signer) error { var ( err error - gas, sysgas fixedn.Fixed8 signersAccounts []actor.SignerAccount resp *result.Invoke signAndPush = acc != nil @@ -676,8 +657,6 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, act *actor.Actor ) if signAndPush { - gas = flags.Fixed8FromContext(ctx, "gas") - sysgas = flags.Fixed8FromContext(ctx, "sysgas") signersAccounts, err = cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.None) if err != nil { return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) @@ -731,44 +710,16 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, } fmt.Fprintln(ctx.App.Writer, string(b)) - } else { - if len(resp.Script) == 0 { - return cli.NewExitError(errors.New("no script returned from the RPC node"), 1) - } - ver := act.GetVersion() - tx, err := act.MakeUnsignedUncheckedRun(resp.Script, resp.GasConsumed+int64(sysgas), nil) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1) - } - tx.NetworkFee += int64(gas) - if out != "" { - // Make a long-lived transaction, it's to be signed manually. - tx.ValidUntilBlock += (ver.Protocol.MaxValidUntilBlockIncrement - uint32(ver.Protocol.ValidatorsCount)) - 2 - m := act.GetNetwork() - if err := paramcontext.InitAndSave(m, tx, acc, out); err != nil { - return cli.NewExitError(err, 1) - } - fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE()) - } else { - if !ctx.Bool("force") { - promptTime := time.Now() - err := input.ConfirmTx(ctx.App.Writer, tx) - if err != nil { - return cli.NewExitError(err, 1) - } - waitTime := time.Since(promptTime) - // Compensate for confirmation waiting. - tx.ValidUntilBlock += uint32((waitTime.Milliseconds() / int64(ver.Protocol.MillisecondsPerBlock))) + 1 - } - txHash, _, err := act.SignAndSend(tx) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1) - } - fmt.Fprintf(ctx.App.Writer, "Sent invocation transaction %s\n", txHash.StringLE()) - } + return nil } - - return nil + if len(resp.Script) == 0 { + return cli.NewExitError(errors.New("no script returned from the RPC node"), 1) + } + tx, err := act.MakeUnsignedUncheckedRun(resp.Script, resp.GasConsumed, nil) + if err != nil { + return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1) + } + return txctx.SignAndSend(ctx, act, acc, tx) } func testInvokeScript(ctx *cli.Context) error { diff --git a/cli/txctx/tx.go b/cli/txctx/tx.go new file mode 100644 index 000000000..64a6b0f67 --- /dev/null +++ b/cli/txctx/tx.go @@ -0,0 +1,79 @@ +/* +Package txctx contains helper functions that deal with transactions in CLI context. +*/ +package txctx + +import ( + "fmt" + "time" + + "github.com/nspcc-dev/neo-go/cli/flags" + "github.com/nspcc-dev/neo-go/cli/input" + "github.com/nspcc-dev/neo-go/cli/paramcontext" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" + "github.com/nspcc-dev/neo-go/pkg/wallet" + "github.com/urfave/cli" +) + +var ( + // GasFlag is a flag used for the additional network fee. + GasFlag = flags.Fixed8Flag{ + Name: "gas, g", + Usage: "network fee to add to the transaction (prioritizing it)", + } + // SysGasFlag is a flag used for the additional system fee. + SysGasFlag = flags.Fixed8Flag{ + Name: "sysgas, e", + Usage: "system fee to add to the transaction (compensating for execution)", + } + // OutFlag is a flag used for file output. + OutFlag = cli.StringFlag{ + Name: "out", + Usage: "file (JSON) to put signature context with a transaction to", + } + // ForceFlag is a flag used to force transaction send. + ForceFlag = cli.BoolFlag{ + Name: "force", + Usage: "Do not ask for a confirmation (and ignore errors)", + } +) + +// SignAndSend adds network and system fees to the provided transaction and +// either sends it to the network (with a confirmation or --force flag) or saves +// it into a file (given in the --out flag). +func SignAndSend(ctx *cli.Context, act *actor.Actor, acc *wallet.Account, tx *transaction.Transaction) error { + var ( + err error + gas = flags.Fixed8FromContext(ctx, "gas") + sysgas = flags.Fixed8FromContext(ctx, "sysgas") + ver = act.GetVersion() + ) + + tx.SystemFee += int64(sysgas) + tx.NetworkFee += int64(gas) + + if outFile := ctx.String("out"); outFile != "" { + // Make a long-lived transaction, it's to be signed manually. + tx.ValidUntilBlock += (ver.Protocol.MaxValidUntilBlockIncrement - uint32(ver.Protocol.ValidatorsCount)) - 2 + err = paramcontext.InitAndSave(ver.Protocol.Network, tx, acc, outFile) + } else { + if !ctx.Bool("force") { + promptTime := time.Now() + err := input.ConfirmTx(ctx.App.Writer, tx) + if err != nil { + return cli.NewExitError(err, 1) + } + waitTime := time.Since(promptTime) + // Compensate for confirmation waiting. + tx.ValidUntilBlock += uint32((waitTime.Milliseconds() / int64(ver.Protocol.MillisecondsPerBlock))) + 1 + } + _, _, err = act.SignAndSend(tx) + } + if err != nil { + return cli.NewExitError(err, 1) + } + + fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE()) + return nil +} diff --git a/cli/wallet/candidate_test.go b/cli/wallet/candidate_test.go index 9f59f870b..822d764f4 100644 --- a/cli/wallet/candidate_test.go +++ b/cli/wallet/candidate_test.go @@ -55,7 +55,8 @@ func TestRegisterCandidate(t *testing.T) { e.Run(t, "neo-go", "wallet", "candidate", "register", "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", testcli.ValidatorWallet, - "--address", validatorAddress) + "--address", validatorAddress, + "--force") e.CheckTxPersisted(t) vs, err := e.Chain.GetEnrollments() @@ -77,7 +78,8 @@ func TestRegisterCandidate(t *testing.T) { "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", testcli.ValidatorWallet, "--address", validatorAddress, - "--candidate", validatorHex) + "--candidate", validatorHex, + "--force") _, index := e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() @@ -110,7 +112,8 @@ func TestRegisterCandidate(t *testing.T) { e.Run(t, "neo-go", "wallet", "candidate", "vote", "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", testcli.ValidatorWallet, - "--address", validatorAddress) + "--address", validatorAddress, + "--force") _, index = e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() @@ -143,7 +146,8 @@ func TestRegisterCandidate(t *testing.T) { e.Run(t, "neo-go", "wallet", "candidate", "unregister", "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", testcli.ValidatorWallet, - "--address", validatorAddress) + "--address", validatorAddress, + "--force") e.CheckTxPersisted(t) vs, err = e.Chain.GetEnrollments() diff --git a/cli/wallet/nep11.go b/cli/wallet/nep11.go index 5fb8c950e..8c5b9caf6 100644 --- a/cli/wallet/nep11.go +++ b/cli/wallet/nep11.go @@ -9,6 +9,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/options" + "github.com/nspcc-dev/neo-go/cli/txctx" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/neorpc/result" @@ -94,7 +95,7 @@ func newNEP11Commands() []cli.Command { walletPathFlag, walletConfigFlag, tokenFlag, - forceFlag, + txctx.ForceFlag, }, }, { diff --git a/cli/wallet/nep17.go b/cli/wallet/nep17.go index 6a778cfa3..7a7ad5a4e 100644 --- a/cli/wallet/nep17.go +++ b/cli/wallet/nep17.go @@ -6,13 +6,11 @@ import ( "fmt" "math/big" "strings" - "time" "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/cli/txctx" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/encoding/address" @@ -37,14 +35,6 @@ var ( Name: "token", Usage: "Token to use (hash or name (for NEO/GAS or imported tokens))", } - gasFlag = flags.Fixed8Flag{ - Name: "gas, g", - Usage: "network fee to add to the transaction (prioritizing it)", - } - sysGasFlag = flags.Fixed8Flag{ - Name: "sysgas, e", - Usage: "system fee to add to transaction (compensating for execution)", - } baseBalanceFlags = []cli.Flag{ walletPathFlag, walletConfigFlag, @@ -65,13 +55,13 @@ var ( baseTransferFlags = []cli.Flag{ walletPathFlag, walletConfigFlag, - outFlag, + txctx.OutFlag, fromAddrFlag, toAddrFlag, tokenFlag, - gasFlag, - sysGasFlag, - forceFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.ForceFlag, cli.StringFlag{ Name: "amount", Usage: "Amount of asset to send", @@ -80,11 +70,11 @@ var ( multiTransferFlags = append([]cli.Flag{ walletPathFlag, walletConfigFlag, - outFlag, + txctx.OutFlag, fromAddrFlag, - gasFlag, - sysGasFlag, - forceFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.ForceFlag, }, options.RPC...) ) @@ -143,7 +133,7 @@ func newNEP17Commands() []cli.Command { walletPathFlag, walletConfigFlag, tokenFlag, - forceFlag, + txctx.ForceFlag, }, }, { @@ -599,7 +589,7 @@ func multiTransferNEP17(ctx *cli.Context) error { if err != nil { return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1) } - return signAndSendSomeTransaction(ctx, act, acc, tx) + return txctx.SignAndSend(ctx, act, acc, tx) } func transferNEP17(ctx *cli.Context) error { @@ -697,7 +687,7 @@ func transferNEP(ctx *cli.Context, standard string) error { return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1) } - return signAndSendSomeTransaction(ctx, act, acc, tx) + return txctx.SignAndSend(ctx, act, acc, tx) } func makeMultiTransferNEP17(act *actor.Actor, recipients []rpcclient.TransferTarget) (*transaction.Transaction, error) { @@ -713,42 +703,6 @@ func makeMultiTransferNEP17(act *actor.Actor, recipients []rpcclient.TransferTar return act.MakeUnsignedRun(script, nil) } -func signAndSendSomeTransaction(ctx *cli.Context, act *actor.Actor, acc *wallet.Account, tx *transaction.Transaction) error { - var ( - err error - gas = flags.Fixed8FromContext(ctx, "gas") - sysgas = flags.Fixed8FromContext(ctx, "sysgas") - ) - - tx.SystemFee += int64(sysgas) - tx.NetworkFee += int64(gas) - - ver := act.GetVersion() - if outFile := ctx.String("out"); outFile != "" { - // Make a long-lived transaction, it's to be signed manually. - tx.ValidUntilBlock += (ver.Protocol.MaxValidUntilBlockIncrement - uint32(ver.Protocol.ValidatorsCount)) - 2 - err = paramcontext.InitAndSave(ver.Protocol.Network, tx, acc, outFile) - } else { - if !ctx.Bool("force") { - promptTime := time.Now() - err := input.ConfirmTx(ctx.App.Writer, tx) - if err != nil { - return cli.NewExitError(err, 1) - } - waitTime := time.Since(promptTime) - // Compensate for confirmation waiting. - tx.ValidUntilBlock += uint32((waitTime.Milliseconds() / int64(ver.Protocol.MillisecondsPerBlock))) + 1 - } - _, _, err = act.SignAndSend(tx) - } - if err != nil { - return cli.NewExitError(err, 1) - } - - fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE()) - return nil -} - func getDefaultAddress(fromFlag *flags.Address, w *wallet.Wallet) (util.Uint160, error) { if fromFlag.IsSet { return fromFlag.Uint160(), nil diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index 2bc246298..1194fa371 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -7,6 +7,7 @@ import ( "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/txctx" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" @@ -22,12 +23,15 @@ func newValidatorCommands() []cli.Command { { Name: "register", Usage: "register as a new candidate", - UsageText: "register -w -r -a ", + UsageText: "register -w -r -a [-g gas] [-e sysgas] [--out file] [--force]", Action: handleRegister, Flags: append([]cli.Flag{ walletPathFlag, walletConfigFlag, - gasFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.OutFlag, + txctx.ForceFlag, flags.AddressFlag{ Name: "address, a", Usage: "Address to register", @@ -37,12 +41,15 @@ func newValidatorCommands() []cli.Command { { Name: "unregister", Usage: "unregister self as a candidate", - UsageText: "unregister -w -r -a ", + UsageText: "unregister -w -r -a [-g gas] [-e sysgas] [--out file] [--force]", Action: handleUnregister, Flags: append([]cli.Flag{ walletPathFlag, walletConfigFlag, - gasFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.OutFlag, + txctx.ForceFlag, flags.AddressFlag{ Name: "address, a", Usage: "Address to unregister", @@ -52,7 +59,7 @@ func newValidatorCommands() []cli.Command { { Name: "vote", Usage: "vote for a validator", - UsageText: "vote -w -r [-s ] [-g gas] -a [-c ]", + UsageText: "vote -w -r [-s ] [-g gas] [-e sysgas] -a [-c ] [--out file] [--force]", Description: `Votes for a validator by calling "vote" method of a NEO native contract. Do not provide candidate argument to perform unvoting. `, @@ -60,7 +67,10 @@ func newValidatorCommands() []cli.Command { Flags: append([]cli.Flag{ walletPathFlag, walletConfigFlag, - gasFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.OutFlag, + txctx.ForceFlag, flags.AddressFlag{ Name: "address, a", Usage: "Address to vote from", @@ -118,19 +128,12 @@ func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *w return cli.NewExitError(fmt.Errorf("RPC actor issue: %w", err), 1) } - gas := flags.Fixed8FromContext(ctx, "gas") contract := neo.New(act) tx, err := mkTx(contract, addr, acc) if err != nil { return cli.NewExitError(err, 1) } - tx.NetworkFee += int64(gas) - res, _, err := act.SignAndSend(tx) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to sign/send transaction: %w", err), 1) - } - fmt.Fprintln(ctx.App.Writer, res.StringLE()) - return nil + return txctx.SignAndSend(ctx, act, acc, tx) } func handleVote(ctx *cli.Context) error { diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index 09479ef71..1e5695ba1 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -14,13 +14,15 @@ import ( "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/txctx" "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/neo" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" + "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/urfave/cli" @@ -63,10 +65,6 @@ var ( Name: "decrypt, d", Usage: "Decrypt encrypted keys.", } - outFlag = cli.StringFlag{ - Name: "out", - Usage: "file to put JSON transaction to", - } inFlag = cli.StringFlag{ Name: "in", Usage: "file with JSON transaction", @@ -79,10 +77,6 @@ var ( Name: "to", Usage: "Address to send an asset to", } - forceFlag = cli.BoolFlag{ - Name: "force", - Usage: "Do not ask for a confirmation", - } ) // NewCommands returns 'wallet' command. @@ -90,6 +84,10 @@ func NewCommands() []cli.Command { claimFlags := []cli.Flag{ walletPathFlag, walletConfigFlag, + txctx.GasFlag, + txctx.SysGasFlag, + txctx.OutFlag, + txctx.ForceFlag, flags.AddressFlag{ Name: "address, a", Usage: "Address to claim GAS for", @@ -99,7 +97,7 @@ func NewCommands() []cli.Command { signFlags := []cli.Flag{ walletPathFlag, walletConfigFlag, - outFlag, + txctx.OutFlag, inFlag, flags.AddressFlag{ Name: "address, a", @@ -114,7 +112,7 @@ func NewCommands() []cli.Command { { Name: "claim", Usage: "claim GAS", - UsageText: "neo-go wallet claim -w wallet [--wallet-config path] -a address -r endpoint [-s timeout]", + UsageText: "neo-go wallet claim -w wallet [--wallet-config path] [-g gas] [-e sysgas] -a address -r endpoint [-s timeout] [--out file] [--force]", Action: claimGas, Flags: claimFlags, }, @@ -282,7 +280,7 @@ func NewCommands() []cli.Command { Flags: []cli.Flag{ walletPathFlag, walletConfigFlag, - forceFlag, + txctx.ForceFlag, flags.AddressFlag{ Name: "address, a", Usage: "Account address or hash in LE form to be removed", @@ -317,7 +315,7 @@ func NewCommands() []cli.Command { Flags: []cli.Flag{ walletPathFlag, walletConfigFlag, - forceFlag, + txctx.ForceFlag, }, }, { @@ -340,45 +338,9 @@ func NewCommands() []cli.Command { } func claimGas(ctx *cli.Context) error { - if err := cmdargs.EnsureNone(ctx); err != nil { - return err - } - wall, pass, err := readWallet(ctx) - if err != nil { - return cli.NewExitError(err, 1) - } - defer wall.Close() - - addrFlag := ctx.Generic("address").(*flags.Address) - if !addrFlag.IsSet { - return cli.NewExitError("address was not provided", 1) - } - scriptHash := addrFlag.Uint160() - acc, err := getDecryptedAccount(wall, scriptHash, pass) - if err != nil { - return cli.NewExitError(err, 1) - } - - gctx, cancel := options.GetTimeoutContext(ctx) - defer cancel() - - c, err := options.GetRPCClient(gctx, ctx) - if err != nil { - return cli.NewExitError(err, 1) - } - - act, err := actor.NewSimple(c, acc) - if err != nil { - return cli.NewExitError(err, 1) - } - neoToken := neo.New(act) - hash, _, err := neoToken.Transfer(scriptHash, scriptHash, big.NewInt(0), nil) - if err != nil { - return cli.NewExitError(err, 1) - } - - fmt.Fprintln(ctx.App.Writer, hash.StringLE()) - return nil + return handleNeoAction(ctx, func(contract *neo.Contract, shash util.Uint160, _ *wallet.Account) (*transaction.Transaction, error) { + return contract.TransferUnsigned(shash, shash, big.NewInt(0), nil) + }) } func changePassword(ctx *cli.Context) error { diff --git a/cli/wallet/wallet_test.go b/cli/wallet/wallet_test.go index db1601b5c..bfab35d38 100644 --- a/cli/wallet/wallet_test.go +++ b/cli/wallet/wallet_test.go @@ -524,7 +524,8 @@ func TestWalletClaimGas(t *testing.T) { e.Run(t, "neo-go", "wallet", "claim", "--rpc-endpoint", "http://"+e.RPC.Addr, "--wallet", testcli.TestWalletPath, - "--address", testcli.TestWalletAccount) + "--address", testcli.TestWalletAccount, + "--force") tx, height := e.CheckTxPersisted(t) balanceBefore.Sub(balanceBefore, big.NewInt(tx.NetworkFee+tx.SystemFee)) balanceBefore.Add(balanceBefore, cl)