cli: unify canceltx command output

Always return "Target transaction accepted" error if the target transation was
either accepted by the moment of command run or during the command
handling. Exit with code 1 in both cases. Adjust TestAwaitUtilCancelTx
correspondingly, allow both cases in test. Simplify the test along the
way, remove useless code.

Close #3365.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2024-04-01 20:51:33 +03:00
parent 309016561d
commit e0e7fdf810
3 changed files with 30 additions and 28 deletions

View file

@ -52,7 +52,7 @@ func cancelTx(ctx *cli.Context) error {
mainTx, _ := c.GetRawTransactionVerbose(txHash) mainTx, _ := c.GetRawTransactionVerbose(txHash)
if mainTx != nil && !mainTx.Blockhash.Equals(util.Uint256{}) { if mainTx != nil && !mainTx.Blockhash.Equals(util.Uint256{}) {
return cli.NewExitError(fmt.Errorf("transaction %s is already accepted at block %s", txHash, mainTx.Blockhash.StringLE()), 1) return cli.NewExitError(fmt.Errorf("target transaction %s is accepted at block %s", txHash, mainTx.Blockhash.StringLE()), 1)
} }
if mainTx != nil && !mainTx.HasSigner(acc.ScriptHash()) { if mainTx != nil && !mainTx.HasSigner(acc.ScriptHash()) {
@ -76,10 +76,7 @@ func cancelTx(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to send conflicting transaction: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to send conflicting transaction: %w", err), 1)
} }
var ( var res *state.AppExecResult
acceptedH = resHash
res *state.AppExecResult
)
if ctx.Bool("await") { if ctx.Bool("await") {
res, err = a.WaitAny(gctx, resVub, txHash, resHash) res, err = a.WaitAny(gctx, resVub, txHash, resHash)
if err != nil { if err != nil {
@ -93,12 +90,14 @@ func cancelTx(ctx *cli.Context) error {
return cli.NewExitError(fmt.Errorf("failed to await target/ conflicting transaction %s/ %s: %w", txHash.StringLE(), resHash.StringLE(), err), 1) return cli.NewExitError(fmt.Errorf("failed to await target/ conflicting transaction %s/ %s: %w", txHash.StringLE(), resHash.StringLE(), err), 1)
} }
if txHash.Equals(res.Container) { if txHash.Equals(res.Container) {
fmt.Fprintln(ctx.App.Writer, "Target transaction accepted") tx, err := c.GetRawTransactionVerbose(txHash)
acceptedH = txHash if err != nil {
} else { return cli.NewExitError(fmt.Errorf("target transaction %s is accepted", txHash), 1)
}
return cli.NewExitError(fmt.Errorf("target transaction %s is accepted at block %s", txHash, tx.Blockhash.StringLE()), 1)
}
fmt.Fprintln(ctx.App.Writer, "Conflicting transaction accepted") fmt.Fprintln(ctx.App.Writer, "Conflicting transaction accepted")
} }
} txctx.DumpTransactionInfo(ctx.App.Writer, resHash, res)
txctx.DumpTransactionInfo(ctx.App.Writer, acceptedH, res)
return nil return nil
} }

View file

@ -1,9 +1,9 @@
package util_test package util_test
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"time" "time"
@ -168,24 +168,13 @@ func TestAwaitUtilCancelTx(t *testing.T) {
_, ok := e.Chain.GetMemPool().TryGetValue(txHash) _, ok := e.Chain.GetMemPool().TryGetValue(txHash)
require.True(t, ok) require.True(t, ok)
// Allow both cases: either target or conflicting tx acceptance.
e.In.WriteString("one\r") e.In.WriteString("one\r")
e.Run(t, append(args, txHash.StringLE())...) err = e.RunOrError(t, fmt.Sprintf("target transaction %s is accepted", txHash), append(args, txHash.StringLE())...)
if err == nil {
response := e.GetNextLine(t) response := e.GetNextLine(t)
if strings.Contains(response, "Conflicting transaction accepted") { require.Equal(t, "Conflicting transaction accepted", response)
resHash, _ := e.CheckAwaitableTxPersisted(t) resHash, _ := e.CheckAwaitableTxPersisted(t)
require.Eventually(t, func() bool { require.NotEqual(t, resHash, txHash)
_, aerErr := e.Chain.GetAppExecResults(resHash.Hash(), trigger.Application)
return aerErr == nil
}, time.Second*2, time.Millisecond*50)
} else if strings.Contains(response, "Target transaction accepted") {
require.Eventually(t, func() bool {
_, _, err := e.Chain.GetTransaction(txHash)
require.NoError(t, err, "original transaction should be on chain")
_, aerErr := e.Chain.GetAppExecResults(txHash, trigger.Application)
return aerErr == nil
}, time.Second*2, time.Millisecond*50)
} else {
t.Fatalf("unexpected response: %s", response)
} }
} }

View file

@ -286,6 +286,20 @@ func (e *Executor) Run(t *testing.T, args ...string) {
require.NoError(t, e.run(args...)) require.NoError(t, e.run(args...))
checkExit(t, ch, 0) checkExit(t, ch, 0)
} }
// RunOrError runs command and checks that if there was an error, then its text matches the provided one.
func (e *Executor) RunOrError(t *testing.T, errText string, args ...string) error {
ch := setExitFunc()
err := e.run(args...)
if err != nil {
require.True(t, strings.Contains(err.Error(), errText))
checkExit(t, ch, 1)
} else {
checkExit(t, ch, 0)
}
return err
}
func (e *Executor) run(args ...string) error { func (e *Executor) run(args ...string) error {
e.Out.Reset() e.Out.Reset()
e.Err.Reset() e.Err.Reset()