From 8bdbac3c5e6d6171e2fb3be9e44ccd897b3b9287 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 7 Dec 2023 10:35:37 +0300 Subject: [PATCH] cli: move actor-related functions handling to options package Move actor handling into CLI package. GetRPCWithActor returns RPC with actor instances. Close #2682. Signed-off-by: Ekaterina Pavlova --- cli/options/options.go | 16 +++++++ cli/smartcontract/smart_contract.go | 11 ++--- cli/util/cancel.go | 25 +++++----- cli/wallet/nep17.go | 74 ++++++++++++++--------------- cli/wallet/validator.go | 12 ++--- 5 files changed, 72 insertions(+), 66 deletions(-) diff --git a/cli/options/options.go b/cli/options/options.go index 61e13e353..1cef56915 100644 --- a/cli/options/options.go +++ b/cli/options/options.go @@ -22,6 +22,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/rpcclient" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" @@ -288,6 +289,21 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. return log, &cc.Level, _winfileSinkCloser, err } +// GetRPCWithActor returns an RPC client instance and Actor instance for the given context. +func GetRPCWithActor(gctx context.Context, ctx *cli.Context, signers []actor.SignerAccount) (*rpcclient.Client, *actor.Actor, cli.ExitCoder) { + c, err := GetRPCClient(gctx, ctx) + if err != nil { + return nil, nil, err + } + + a, actorErr := actor.New(c, signers) + if actorErr != nil { + c.Close() + return nil, nil, cli.NewExitError(fmt.Errorf("failed to create Actor: %w", actorErr), 1) + } + return c, a, nil +} + // GetAccFromContext returns account and wallet from context. If address is not set, default address is used. func GetAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error) { var addr util.Uint160 diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 0dcb81b7e..ec3fe68fc 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -592,19 +592,14 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, } gctx, cancel := options.GetTimeoutContext(ctx) defer cancel() - - c, err := options.GetRPCClient(gctx, ctx) - if err != nil { - return err - } if signAndPush { - act, err = actor.New(c, signersAccounts) + _, act, err = options.GetRPCWithActor(gctx, ctx, signersAccounts) if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1) + return err } inv = &act.Invoker } else { - inv, err = options.GetInvoker(c, ctx, cosigners) + _, inv, err = options.GetRPCWithInvoker(gctx, ctx, cosigners) if err != nil { return err } diff --git a/cli/util/cancel.go b/cli/util/cancel.go index ccbe7e63f..495704e3e 100644 --- a/cli/util/cancel.go +++ b/cli/util/cancel.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "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/pkg/core/transaction" @@ -30,30 +31,30 @@ func cancelTx(ctx *cli.Context) error { gctx, cancel := options.GetTimeoutContext(ctx) defer cancel() - c, err := options.GetRPCClient(gctx, ctx) + acc, w, err := options.GetAccFromContext(ctx) if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create RPC client: %w", err), 1) + return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1) + } + defer w.Close() + + signers, err := cmdargs.GetSignersAccounts(acc, w, nil, transaction.CalledByEntry) + if err != nil { + return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) + } + c, a, exitErr := options.GetRPCWithActor(gctx, ctx, signers) + if exitErr != nil { + return exitErr } mainTx, _ := c.GetRawTransactionVerbose(txHash) 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) } - acc, w, err = options.GetAccFromContext(ctx) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1) - } - defer w.Close() if mainTx != nil && !mainTx.HasSigner(acc.ScriptHash()) { return cli.NewExitError(fmt.Errorf("account %s is not a signer of the conflicting transaction", acc.Address), 1) } - a, err := actor.NewSimple(c, acc) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create Actor: %w", err), 1) - } - resHash, _, err := a.SendTunedRun([]byte{byte(opcode.RET)}, []transaction.Attribute{{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: txHash}}}, func(r *result.Invoke, t *transaction.Transaction) error { err := actor.DefaultCheckerModifier(r, t) if err != nil { diff --git a/cli/wallet/nep17.go b/cli/wallet/nep17.go index bb013d264..27ef1d46c 100644 --- a/cli/wallet/nep17.go +++ b/cli/wallet/nep17.go @@ -530,11 +530,6 @@ func multiTransferNEP17(ctx *cli.Context) error { gctx, cancel := options.GetTimeoutContext(ctx) defer cancel() - c, err := options.GetRPCClient(gctx, ctx) - if err != nil { - return cli.NewExitError(err, 1) - } - if ctx.NArg() == 0 { return cli.NewExitError("empty recipients list", 1) } @@ -542,13 +537,32 @@ func multiTransferNEP17(ctx *cli.Context) error { recipients []transferTarget cosignersOffset = ctx.NArg() ) - cache := make(map[string]*wallet.Token) for i := 0; i < ctx.NArg(); i++ { arg := ctx.Args().Get(i) if arg == cmdargs.CosignersSeparator { cosignersOffset = i + 1 break } + } + cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset) + if extErr != nil { + return extErr + } + signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry) + if err != nil { + return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) + } + c, act, exitErr := options.GetRPCWithActor(gctx, ctx, signersAccounts) + if exitErr != nil { + return exitErr + } + + cache := make(map[string]*wallet.Token) + for i := 0; i < cosignersOffset; i++ { + arg := ctx.Args().Get(i) + if arg == cmdargs.CosignersSeparator { + break + } ss := strings.SplitN(arg, ":", 3) if len(ss) != 3 { return cli.NewExitError("send format must be '::", 1) @@ -580,19 +594,6 @@ func multiTransferNEP17(ctx *cli.Context) error { }) } - cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset) - if extErr != nil { - return extErr - } - signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry) - if err != nil { - return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) - } - act, err := actor.New(c, signersAccounts) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1) - } - tx, err := makeMultiTransferNEP17(act, recipients) if err != nil { return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1) @@ -626,9 +627,22 @@ func transferNEP(ctx *cli.Context, standard string) error { gctx, cancel := options.GetTimeoutContext(ctx) defer cancel() - c, err := options.GetRPCClient(gctx, ctx) + cosignersOffset, data, extErr := cmdargs.GetDataFromContext(ctx) + if extErr != nil { + return extErr + } + cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset) + if extErr != nil { + return extErr + } + signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry) if err != nil { - return cli.NewExitError(err, 1) + return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) + } + + c, act, exitErr := options.GetRPCWithActor(gctx, ctx, signersAccounts) + if exitErr != nil { + return exitErr } toFlag := ctx.Generic("to").(*flags.Address) @@ -644,24 +658,6 @@ func transferNEP(ctx *cli.Context, standard string) error { } } - cosignersOffset, data, extErr := cmdargs.GetDataFromContext(ctx) - if extErr != nil { - return extErr - } - - cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset) - if extErr != nil { - return extErr - } - signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry) - if err != nil { - return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) - } - act, err := actor.New(c, signersAccounts) - if err != nil { - return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1) - } - amountArg := ctx.String("amount") amount, err := fixedn.FromString(amountArg, int(token.Decimals)) // It's OK for NEP-11 transfer to not have amount set. diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index 5eaa2b38e..930d73cb0 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -9,8 +9,6 @@ import ( "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" - "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/util" "github.com/nspcc-dev/neo-go/pkg/wallet" @@ -118,13 +116,13 @@ func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *w gctx, cancel := options.GetTimeoutContext(ctx) defer cancel() - c, err := options.GetRPCClient(gctx, ctx) + signers, err := cmdargs.GetSignersAccounts(acc, wall, nil, transaction.CalledByEntry) if err != nil { - return cli.NewExitError(err, 1) + return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1) } - act, err := actor.NewSimple(c, acc) - if err != nil { - return cli.NewExitError(fmt.Errorf("RPC actor issue: %w", err), 1) + _, act, exitErr := options.GetRPCWithActor(gctx, ctx, signers) + if exitErr != nil { + return exitErr } contract := neo.New(act)