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 message
s 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.
proto.MessageName
takes in aprotoreflect.ProtoMessage
, butMsgStartThingRequest
doesn't have aProtoReflect()
method, so&MsgStartThingRequest{}
is an invalid argument for that function.- The
proto.Message
type that the function takes in, is just an alias for thatprotoreflect.ProtoMessage
. SomsgIn
cannot be asserted as a(*MsgStartThingRequest)
because again,MsgStartThingRequest
does not have aProtoReflect()
method.
Metadata
Assignees
Type
Projects
Status
📋 Backlog
Activity