Skip to content

Commit

Permalink
add tests for from flag
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt committed Oct 4, 2023
1 parent 77f5068 commit d0c4b43
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
11 changes: 6 additions & 5 deletions client/v2/autocli/flag/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
}

fields := messageType.Descriptor().Fields()
signerFieldName := getSignerFieldName(messageType.Descriptor())
signerFieldName := GetSignerFieldName(messageType.Descriptor())

isPositional := map[string]bool{}

Expand Down Expand Up @@ -200,8 +200,9 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
flagOptsByFlagName := map[string]*autocliv1.FlagOptions{}
for i := 0; i < fields.Len(); i++ {
field := fields.Get(i)
// skips positional args and signer field
if isPositional[string(field.Name())] || string(field.Name()) == signerFieldName {
// skips positional args and signer field if already set
if isPositional[string(field.Name())] ||
(string(field.Name()) == signerFieldName && messageBinder.SignerInfo.FieldName == flags.FlagFrom) {
continue
}

Expand Down Expand Up @@ -412,9 +413,9 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type
}
}

// getSignerFieldName gets signer field name of a message.
// GetSignerFieldName gets signer field name of a message.
// AutoCLI supports only one signer field per message.
func getSignerFieldName(descriptor protoreflect.MessageDescriptor) string {
func GetSignerFieldName(descriptor protoreflect.MessageDescriptor) string {
signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string)
if len(signersFields) == 0 {
return ""
Expand Down
13 changes: 13 additions & 0 deletions client/v2/autocli/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"google.golang.org/protobuf/types/dynamicpb"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"

"github.com/cosmos/cosmos-sdk/client"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
Expand Down Expand Up @@ -127,6 +128,18 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
clientCtx = clientCtx.WithTxConfig(txConfigWithTextual)
clientCtx.Output = cmd.OutOrStdout()

// set signer to signer field if empty
fd := input.Descriptor().Fields().ByName(protoreflect.Name(flag.GetSignerFieldName(input.Descriptor())))
if addr := input.Get(fd).String(); addr == "" {
signerFromFlag := clientCtx.GetFromAddress()
signer, err := b.ClientCtx.AddressCodec.BytesToString(signerFromFlag.Bytes())
if err != nil {
return fmt.Errorf("failed to set signer on message, got %v: %w", signerFromFlag, err)
}

input.Set(fd, protoreflect.ValueOfString(signer))
}

// AutoCLI uses protov2 messages, while the SDK only supports proto v1 messages.
// Here we use dynamicpb, to create a proto v1 compatible message.
// The SDK codec will handle protov2 -> protov1 (marshal)
Expand Down
52 changes: 52 additions & 0 deletions client/v2/autocli/msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command,
return cmd, err
}

func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, b *Builder) (*cobra.Command, error) {
return func(moduleName string, b *Builder) (*cobra.Command, error) {
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
return cmd, err
}
}

var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
Expand All @@ -41,6 +49,50 @@ func TestMsg(t *testing.T) {
)
assert.NilError(t, err)
golden.Assert(t, out.String(), "msg-output.golden")

out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "Send",
Use: "send [from_key_or_address] [to_address] [amount] [flags]",
Short: "Send coins from one account to another",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
// from_address should be automatically added
},
},
EnhanceCustomCommand: true,
}), "send",
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--from", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
"--generate-only",
"--output", "json",
)
assert.NilError(t, err)
golden.Assert(t, out.String(), "msg-output.golden")

out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "Send",
Use: "send [from_key_or_address] [to_address] [amount] [flags]",
Short: "Send coins from one account to another",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
FlagOptions: map[string]*autocliv1.FlagOptions{
"from_address": {Name: "sender"}, // use a custom flag for signer
},
},
},
EnhanceCustomCommand: true,
}), "send",
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--sender", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
"--generate-only",
"--output", "json",
)
assert.NilError(t, err)
golden.Assert(t, out.String(), "msg-output.golden")
}

func TestMsgOptionsError(t *testing.T) {
Expand Down

0 comments on commit d0c4b43

Please sign in to comment.