diff --git a/cli/vm/cli.go b/cli/vm/cli.go index 7ee1cb366..50e71ea45 100644 --- a/cli/vm/cli.go +++ b/cli/vm/cli.go @@ -151,9 +151,11 @@ Example: { Name: "loadnef", Usage: "Load a NEF-consistent script into the VM optionally attaching to it provided signers with scopes", - UsageText: `loadnef [--historic ] [--gas ] [-- , ...]`, + UsageText: `loadnef [--historic ] [--gas ] [] [-- , ...]`, Flags: []cli.Flag{historicFlag, gasFlag}, - Description: ` and parameters are mandatory. + Description: ` parameter is mandatory, parameter (if omitted) will + be guessed from the parameter by replacing '.nef' suffix with '.manifest.json' + suffix. ` + cmdargs.SignersParsingDoc + ` @@ -671,10 +673,36 @@ func prepareVM(c *cli.Context, tx *transaction.Transaction) error { func handleLoadNEF(c *cli.Context) error { args := c.Args() - if len(args) < 2 { - return fmt.Errorf("%w: ", ErrMissingParameter) + if len(args) < 1 { + return fmt.Errorf("%w: is required", ErrMissingParameter) } - b, err := os.ReadFile(args[0]) + nefFile := args[0] + var ( + manifestFile string + signersStartOffset int + ) + if len(args) == 2 { + manifestFile = args[1] + } else if len(args) == 3 { + if args[1] != cmdargs.CosignersSeparator { + return fmt.Errorf("%w: `%s` was expected as the second parameter, got %s", ErrInvalidParameter, cmdargs.CosignersSeparator, args[1]) + } + signersStartOffset = 2 + } else if len(args) > 3 { + if args[1] == cmdargs.CosignersSeparator { + signersStartOffset = 2 + } else { + manifestFile = args[1] + if args[2] != cmdargs.CosignersSeparator { + return fmt.Errorf("%w: `%s` was expected as the third parameter, got %s", ErrInvalidParameter, cmdargs.CosignersSeparator, args[2]) + } + signersStartOffset = 3 + } + } + if len(manifestFile) == 0 { + manifestFile = strings.TrimSuffix(nefFile, ".nef") + ".manifest.json" + } + b, err := os.ReadFile(nefFile) if err != nil { return err } @@ -682,21 +710,15 @@ func handleLoadNEF(c *cli.Context) error { if err != nil { return fmt.Errorf("failed to decode NEF file: %w", err) } - m, err := getManifestFromFile(args[1]) + m, err := getManifestFromFile(manifestFile) if err != nil { return fmt.Errorf("failed to read manifest: %w", err) } var signers []transaction.Signer - if len(args) > 2 { - if args[2] != cmdargs.CosignersSeparator { - return fmt.Errorf("%w: `%s` was expected as the third parameter, got %s", ErrInvalidParameter, cmdargs.CosignersSeparator, args[2]) - } - if len(args) < 4 { - return fmt.Errorf("%w: signers expected after `%s`, got none", ErrInvalidParameter, cmdargs.CosignersSeparator) - } - signers, err = cmdargs.ParseSigners(c.Args()[3:]) + if signersStartOffset != 0 && len(args) > signersStartOffset { + signers, err = cmdargs.ParseSigners(c.Args()[signersStartOffset:]) if err != nil { - return fmt.Errorf("%w: %v", ErrInvalidParameter, err) //nolint:errorlint // errorlint: non-wrapping format verb for fmt.Errorf. Use `%w` to format errors + return fmt.Errorf("%w: failed to parse signers: %v", ErrInvalidParameter, err) //nolint:errorlint // errorlint: non-wrapping format verb for fmt.Errorf. Use `%w` to format errors } } err = prepareVM(c, createFakeTransaction(nef.Script, signers)) diff --git a/cli/vm/cli_test.go b/cli/vm/cli_test.go index 843782143..8cae8d017 100644 --- a/cli/vm/cli_test.go +++ b/cli/vm/cli_test.go @@ -527,7 +527,17 @@ go 1.18`) "loadnef "+filename+" "+notExists, "loadnef "+filename+" "+filename, "loadnef "+filename+" "+manifestFile, - "run main add 3 5") + "run main add 3 5", + "loadnef "+filename, + "run main add 3 5", + "loadnef "+filename+" "+cmdargs.CosignersSeparator, + "loadnef "+filename+" "+manifestFile+" "+cmdargs.CosignersSeparator, + "loadnef "+filename+" "+manifestFile+" "+"not-a-separator", + "loadnef "+filename+" "+cmdargs.CosignersSeparator+" "+util.Uint160{1, 2, 3}.StringLE(), + "run main add 3 5", + "loadnef "+filename+" "+manifestFile+" "+cmdargs.CosignersSeparator+" "+util.Uint160{1, 2, 3}.StringLE(), + "run main add 3 5", + ) e.checkError(t, ErrMissingParameter) e.checkNextLine(t, "Error:") @@ -535,6 +545,15 @@ go 1.18`) e.checkNextLine(t, "Error:") e.checkNextLine(t, "READY: loaded \\d* instructions") e.checkStack(t, 8) + e.checkNextLine(t, "READY: loaded \\d* instructions") + e.checkStack(t, 8) + e.checkNextLine(t, "Error:") // manifest missing, missing signer after -- + e.checkNextLine(t, "Error:") // manifest present, missing signer after -- + e.checkNextLine(t, "Error:") // manifest present, invalid separator + e.checkNextLine(t, "READY: loaded \\d* instructions") // manifest missing, signer present, OK + e.checkStack(t, 8) + e.checkNextLine(t, "READY: loaded \\d* instructions") // manifest present, signer present, OK + e.checkStack(t, 8) }) }