mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-01-24 19:24:35 +00:00
cli: move cosigners parsing to a separate function
We have a lot of common code which is shared between `smartcontract` and `wallet` cli packages. It's convinient to keep it in a separate helper package in order to avoid functional cli packages dependencies.
This commit is contained in:
parent
8407ae057c
commit
2ab420ed18
4 changed files with 111 additions and 87 deletions
49
cli/cmdargs/parser.go
Normal file
49
cli/cmdargs/parser.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package cmdargs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetSignersFromContext returns signers parsed from context args starting
|
||||||
|
// from the specified offset.
|
||||||
|
func GetSignersFromContext(ctx *cli.Context, offset int) ([]transaction.Signer, *cli.ExitError) {
|
||||||
|
args := ctx.Args()
|
||||||
|
var signers []transaction.Signer
|
||||||
|
if args.Present() && len(args) > offset {
|
||||||
|
for i, c := range args[offset:] {
|
||||||
|
cosigner, err := parseCosigner(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, cli.NewExitError(fmt.Errorf("failed to parse signer #%d: %w", i, err), 1)
|
||||||
|
}
|
||||||
|
signers = append(signers, cosigner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCosigner(c string) (transaction.Signer, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res = transaction.Signer{
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data := strings.SplitN(c, ":", 2)
|
||||||
|
s := data[0]
|
||||||
|
res.Account, err = flags.ParseAddress(s)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
if len(data) > 1 {
|
||||||
|
res.Scopes, err = transaction.ScopesFromString(data[1])
|
||||||
|
if err != nil {
|
||||||
|
return transaction.Signer{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
54
cli/cmdargs/parser_test.go
Normal file
54
cli/cmdargs/parser_test.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package cmdargs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseCosigner(t *testing.T) {
|
||||||
|
acc := util.Uint160{1, 3, 5, 7}
|
||||||
|
testCases := map[string]transaction.Signer{
|
||||||
|
acc.StringLE(): {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
"0x" + acc.StringLE(): {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
acc.StringLE() + ":Global": {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.Global,
|
||||||
|
},
|
||||||
|
acc.StringLE() + ":CalledByEntry": {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
acc.StringLE() + ":None": {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.None,
|
||||||
|
},
|
||||||
|
acc.StringLE() + ":CalledByEntry,CustomContracts": {
|
||||||
|
Account: acc,
|
||||||
|
Scopes: transaction.CalledByEntry | transaction.CustomContracts,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for s, expected := range testCases {
|
||||||
|
actual, err := parseCosigner(s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
errorCases := []string{
|
||||||
|
acc.StringLE() + "0",
|
||||||
|
acc.StringLE() + ":Unknown",
|
||||||
|
acc.StringLE() + ":Global,CustomContracts",
|
||||||
|
acc.StringLE() + ":Global,None",
|
||||||
|
}
|
||||||
|
for _, s := range errorCases {
|
||||||
|
_, err := parseCosigner(s)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/cli/options"
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
|
@ -513,6 +514,7 @@ func invokeFunction(ctx *cli.Context) error {
|
||||||
func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
exitErr *cli.ExitError
|
||||||
gas fixedn.Fixed8
|
gas fixedn.Fixed8
|
||||||
operation string
|
operation string
|
||||||
params = make([]smartcontract.Parameter, 0)
|
params = make([]smartcontract.Parameter, 0)
|
||||||
|
@ -547,14 +549,9 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
cosignersStart := paramsStart + cosignersOffset
|
cosignersStart := paramsStart + cosignersOffset
|
||||||
if len(args) > cosignersStart {
|
cosigners, exitErr = cmdargs.GetSignersFromContext(ctx, cosignersStart)
|
||||||
for i, c := range args[cosignersStart:] {
|
if exitErr != nil {
|
||||||
cosigner, err := parseCosigner(c)
|
return exitErr
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(fmt.Errorf("failed to parse cosigner #%d: %w", i+1, err), 1)
|
|
||||||
}
|
|
||||||
cosigners = append(cosigners, cosigner)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if signAndPush {
|
if signAndPush {
|
||||||
|
@ -686,16 +683,9 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to restore .nef file: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to restore .nef file: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args := ctx.Args()
|
signers, exitErr := cmdargs.GetSignersFromContext(ctx, 0)
|
||||||
var signers []transaction.Signer
|
if exitErr != nil {
|
||||||
if args.Present() {
|
return exitErr
|
||||||
for i, c := range args[:] {
|
|
||||||
cosigner, err := parseCosigner(c)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(fmt.Errorf("failed to parse signer #%d: %w", i+1, err), 1)
|
|
||||||
}
|
|
||||||
signers = append(signers, cosigner)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||||
|
@ -932,25 +922,3 @@ func ParseContractConfig(confFile string) (ProjectConfig, error) {
|
||||||
}
|
}
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCosigner(c string) (transaction.Signer, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res = transaction.Signer{
|
|
||||||
Scopes: transaction.CalledByEntry,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
data := strings.SplitN(c, ":", 2)
|
|
||||||
s := data[0]
|
|
||||||
res.Account, err = flags.ParseAddress(s)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
if len(data) > 1 {
|
|
||||||
res.Scopes, err = transaction.ScopesFromString(data[1])
|
|
||||||
if err != nil {
|
|
||||||
return transaction.Signer{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,9 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
@ -69,51 +67,6 @@ events:
|
||||||
`, string(manifest))
|
`, string(manifest))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseCosigner(t *testing.T) {
|
|
||||||
acc := util.Uint160{1, 3, 5, 7}
|
|
||||||
testCases := map[string]transaction.Signer{
|
|
||||||
acc.StringLE(): {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.CalledByEntry,
|
|
||||||
},
|
|
||||||
"0x" + acc.StringLE(): {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.CalledByEntry,
|
|
||||||
},
|
|
||||||
acc.StringLE() + ":Global": {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.Global,
|
|
||||||
},
|
|
||||||
acc.StringLE() + ":CalledByEntry": {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.CalledByEntry,
|
|
||||||
},
|
|
||||||
acc.StringLE() + ":None": {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.None,
|
|
||||||
},
|
|
||||||
acc.StringLE() + ":CalledByEntry,CustomContracts": {
|
|
||||||
Account: acc,
|
|
||||||
Scopes: transaction.CalledByEntry | transaction.CustomContracts,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for s, expected := range testCases {
|
|
||||||
actual, err := parseCosigner(s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, expected, actual)
|
|
||||||
}
|
|
||||||
errorCases := []string{
|
|
||||||
acc.StringLE() + "0",
|
|
||||||
acc.StringLE() + ":Unknown",
|
|
||||||
acc.StringLE() + ":Global,CustomContracts",
|
|
||||||
acc.StringLE() + ":Global,None",
|
|
||||||
}
|
|
||||||
for _, s := range errorCases {
|
|
||||||
_, err := parseCosigner(s)
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseParams_CalledFromItself(t *testing.T) {
|
func TestParseParams_CalledFromItself(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
WordsRead int
|
WordsRead int
|
||||||
|
|
Loading…
Reference in a new issue