Skip to content

DefineCustomGetSigners is undocumented. #20077

Open
@SpicyLemon

Description

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

There is no way to use DefineCustomGetSigners on a Msg.

The DefineCustomGetSigners function uses the Message interface defined in "google.golang.org/protobuf/proto". That's an alias for the protoreflect.ProtoMessage interface, which just requires the ProtoReflect() Message method. But code generated from protos does not create that method on anything.

All of the unit tests related to signing uses the pulsar stuff. But those things aren't what are actually used by the msg server. So there's no way to define a custom GetSigners method for anything that someone would be actually signing.

Cosmos SDK Version

0.50.5

How to reproduce?

Here's the simplified situation I'm in where I need to define a custom GetSigners method.

service Msg {
  rpc StartThing(MsgStartThingRequest) MsgStartThingResponse;
  rpc EndThing(MsgEndThingRequest) MsgEndThingResponse;
}

message MsgStartThingRequest {
  Thing thing = 1;
}

message MsgStartThingResponse {}

message MsgEndThingRequest {
  Thing thing = 1;
}

message MsgEndThingResponse {}

message Thing {
  string addr1 = 1  [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string addr2 = 2  [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

The signer of MsgStartThingRequest should be thing.addr1.
The signer of MsgEndThingRequest should be thing.addr2.

I can't use option (cosmos.msg.v1.signer) here because it no longer allows sub-fields. I.e., in MsgStartThingRequest, I can't have option (cosmos.msg.v1.signer) = "thing.addr1", I can only have option (cosmos.msg.v1.signer) = "thing". I'd then have to put an option (cosmos.msg.v1.signer) in the Thing message, but it can't be hard-coded like that because the field that's the signer is different depending on which Msg the Thing is in. And there are other messages that also have a Thing where neither should be a signer.

In the go code, the msg server endpoint methods require the use of the MsgStartThingRequest struct as defined in the auto-generated go code that lives in the module code. Those Msg structs (where we used to have to define GetSigners()), do not have a ProtoReflect() method, though. So it's impossible to define a custom GetSigners function on a Msg required by an endpoint.

Here's what the go code might look like to define the custom GetSigners for MsgStartThingRequest:

	options.DefineCustomGetSigners(proto.MessageName(&MsgStartThingRequest{}), func(msgIn proto.Message) ([][]byte, error) {
		msg, ok := msgIn.(*MsgStartThingRequest)
		if !ok {
			return nil, fmt.Errorf("incorrect message type, actual: %T, expected: %T", msgIn, &MsgStartThingRequest{})
		}
		addr, err := options.AddressCodec.StringToBytes(msgCP.Thing.Addr1)
		if err != nil {
			return nil, err
		}
		return [][]byte{addr}, nil
	})

In that, options is a cosmossdk.io/x/tx/signing.Options, and proto is the google.golang.org/protobuf/proto package.

There are two compilation issues with that code.

  1. proto.MessageName takes in a protoreflect.ProtoMessage, but MsgStartThingRequest doesn't have a ProtoReflect() method, so &MsgStartThingRequest{} is an invalid argument for that function.
  2. The proto.Message type that the function takes in, is just an alias for that protoreflect.ProtoMessage. So msgIn cannot be asserted as a (*MsgStartThingRequest) because again, MsgStartThingRequest does not have a ProtoReflect() method.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    T:DocsChanges and features related to documentation.

    Type

    No type

    Projects

    • Status

      📋 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions