feat!(x/tx): support validator address signers (#15709)
This commit is contained in:
parent
bf17fec0e7
commit
001c11e00d
@ -13,7 +13,7 @@ require (
|
||||
cosmossdk.io/x/evidence v0.1.0
|
||||
cosmossdk.io/x/feegrant v0.0.0-20230117113717-50e7c4a4ceff
|
||||
cosmossdk.io/x/nft v0.0.0-20230113085233-fae3332d62fc
|
||||
cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63
|
||||
cosmossdk.io/x/tx v0.5.1
|
||||
cosmossdk.io/x/upgrade v0.0.0-20230127052425-54c8e1568335
|
||||
github.com/cometbft/cometbft v0.37.1-0.20230411132551-3a91d155e664
|
||||
github.com/cosmos/cosmos-db v1.0.0-rc.1
|
||||
@ -197,7 +197,6 @@ replace (
|
||||
cosmossdk.io/x/evidence => ../x/evidence
|
||||
cosmossdk.io/x/feegrant => ../x/feegrant
|
||||
cosmossdk.io/x/nft => ../x/nft
|
||||
cosmossdk.io/x/tx => ../x/tx
|
||||
cosmossdk.io/x/upgrade => ../x/upgrade
|
||||
)
|
||||
|
||||
|
||||
@ -202,6 +202,8 @@ cosmossdk.io/log v1.0.0 h1:NGKZ/A5rd4PduDfoscgABklX557PWjQINbosZy/m3Jk=
|
||||
cosmossdk.io/log v1.0.0/go.mod h1:CwX9BLiBruZb7lzLlRr3R231d/fVPUXk8gAdV4LQap0=
|
||||
cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw=
|
||||
cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k=
|
||||
cosmossdk.io/x/tx v0.5.1 h1:OcHU8ex3JzxDjexSkMovBx8EnJXcqhrRt7msBq/3vqs=
|
||||
cosmossdk.io/x/tx v0.5.1/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
|
||||
@ -31,10 +31,22 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## Unreleased
|
||||
|
||||
### API Breaking
|
||||
|
||||
* [#15709](https://github.com/cosmos/cosmos-sdk/pull/15709):
|
||||
* `GetSignersContext` has been renamed to `signing.Context`
|
||||
* `GetSigners` now returns `[][]byte` instead of `[]string`
|
||||
* `GetSignersOptions` has been renamed to `signing.Options` and requires `address.Codec`s for account and validator addresses
|
||||
* `GetSignersOptions.ProtoFiles` has been renamed to `signing.Options.FileResolver`
|
||||
|
||||
## v0.5.1
|
||||
|
||||
### Features
|
||||
|
||||
* [#15414](https://github.com/cosmos/cosmos-sdk/pull/15414) Add basic transaction decoding support.
|
||||
|
||||
## v0.5.0
|
||||
|
||||
### API Breaking
|
||||
|
||||
* [#15581](https://github.com/cosmos/cosmos-sdk/pull/15581) `GetSignersOptions` and `directaux.SignModeHandlerOptions` now
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
package decode
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-proto/anyutil"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"fmt"
|
||||
|
||||
v1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
|
||||
"cosmossdk.io/errors"
|
||||
"github.com/cosmos/cosmos-proto/anyutil"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"cosmossdk.io/x/tx/signing"
|
||||
)
|
||||
|
||||
@ -15,51 +16,28 @@ type DecodedTx struct {
|
||||
Messages []proto.Message
|
||||
Tx *v1beta1.Tx
|
||||
TxRaw *v1beta1.TxRaw
|
||||
Signers []string
|
||||
Signers [][]byte
|
||||
TxBodyHasUnknownNonCriticals bool
|
||||
}
|
||||
|
||||
// Decoder contains the dependencies required for decoding transactions.
|
||||
type Decoder struct {
|
||||
getSignersCtx *signing.GetSignersContext
|
||||
typeResolver protoregistry.MessageTypeResolver
|
||||
protoFiles *protoregistry.Files
|
||||
signingCtx *signing.Context
|
||||
}
|
||||
|
||||
// Options are options for creating a Decoder.
|
||||
type Options struct {
|
||||
// ProtoFiles are the protobuf files to use for resolving message descriptors.
|
||||
// If it is nil, the global protobuf registry will be used.
|
||||
ProtoFiles *protoregistry.Files
|
||||
TypeResolver protoregistry.MessageTypeResolver
|
||||
SigningContext *signing.GetSignersContext
|
||||
SigningContext *signing.Context
|
||||
}
|
||||
|
||||
// NewDecoder creates a new Decoder for decoding transactions.
|
||||
func NewDecoder(options Options) (*Decoder, error) {
|
||||
if options.ProtoFiles == nil {
|
||||
options.ProtoFiles = protoregistry.GlobalFiles
|
||||
}
|
||||
|
||||
if options.TypeResolver == nil {
|
||||
options.TypeResolver = protoregistry.GlobalTypes
|
||||
}
|
||||
|
||||
getSignersCtx := options.SigningContext
|
||||
if getSignersCtx == nil {
|
||||
var err error
|
||||
getSignersCtx, err = signing.NewGetSignersContext(signing.GetSignersOptions{
|
||||
ProtoFiles: options.ProtoFiles,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if options.SigningContext == nil {
|
||||
return nil, fmt.Errorf("signing context is required")
|
||||
}
|
||||
|
||||
return &Decoder{
|
||||
getSignersCtx: getSignersCtx,
|
||||
protoFiles: options.ProtoFiles,
|
||||
typeResolver: options.TypeResolver,
|
||||
signingCtx: options.SigningContext,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -74,7 +52,8 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
|
||||
var raw v1beta1.TxRaw
|
||||
|
||||
// reject all unknown proto fields in the root TxRaw
|
||||
err = RejectUnknownFieldsStrict(txBytes, raw.ProtoReflect().Descriptor(), d.protoFiles)
|
||||
fileResolver := d.signingCtx.FileResolver()
|
||||
err = RejectUnknownFieldsStrict(txBytes, raw.ProtoReflect().Descriptor(), fileResolver)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrTxDecode, err.Error())
|
||||
}
|
||||
@ -87,7 +66,7 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
|
||||
var body v1beta1.TxBody
|
||||
|
||||
// allow non-critical unknown fields in TxBody
|
||||
txBodyHasUnknownNonCriticals, err := RejectUnknownFields(raw.BodyBytes, body.ProtoReflect().Descriptor(), true, d.protoFiles)
|
||||
txBodyHasUnknownNonCriticals, err := RejectUnknownFields(raw.BodyBytes, body.ProtoReflect().Descriptor(), true, fileResolver)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrTxDecode, err.Error())
|
||||
}
|
||||
@ -100,7 +79,7 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
|
||||
var authInfo v1beta1.AuthInfo
|
||||
|
||||
// reject all unknown proto fields in AuthInfo
|
||||
err = RejectUnknownFieldsStrict(raw.AuthInfoBytes, authInfo.ProtoReflect().Descriptor(), d.protoFiles)
|
||||
err = RejectUnknownFieldsStrict(raw.AuthInfoBytes, authInfo.ProtoReflect().Descriptor(), fileResolver)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrTxDecode, err.Error())
|
||||
}
|
||||
@ -116,15 +95,15 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
|
||||
Signatures: raw.Signatures,
|
||||
}
|
||||
|
||||
var signers []string
|
||||
var signers [][]byte
|
||||
var msgs []proto.Message
|
||||
for _, anyMsg := range body.Messages {
|
||||
msg, signerErr := anyutil.Unpack(anyMsg, d.protoFiles, d.typeResolver)
|
||||
msg, signerErr := anyutil.Unpack(anyMsg, fileResolver, d.signingCtx.TypeResolver())
|
||||
if signerErr != nil {
|
||||
return nil, errors.Wrap(ErrTxDecode, signerErr.Error())
|
||||
}
|
||||
msgs = append(msgs, msg)
|
||||
ss, signerErr := d.getSignersCtx.GetSigners(msg)
|
||||
ss, signerErr := d.signingCtx.GetSigners(msg)
|
||||
if signerErr != nil {
|
||||
return nil, errors.Wrap(ErrTxDecode, signerErr.Error())
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package decode_test
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@ -9,8 +10,10 @@ import (
|
||||
"cosmossdk.io/api/cosmos/crypto/secp256k1"
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
|
||||
|
||||
"cosmossdk.io/x/tx/decode"
|
||||
"cosmossdk.io/x/tx/internal/testpb"
|
||||
"cosmossdk.io/x/tx/signing"
|
||||
|
||||
"github.com/cosmos/cosmos-proto/anyutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -36,6 +39,16 @@ func TestDecode(t *testing.T) {
|
||||
Sequence: accSeq,
|
||||
})
|
||||
|
||||
signingCtx, err := signing.NewContext(signing.Options{
|
||||
AddressCodec: dummyAddressCodec{},
|
||||
ValidatorAddressCodec: dummyAddressCodec{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
decoder, err := decode.NewDecoder(decode.Options{
|
||||
SigningContext: signingCtx,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
msg proto.Message
|
||||
@ -83,9 +96,6 @@ func TestDecode(t *testing.T) {
|
||||
txBytes, err := proto.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
decoder, err := decode.NewDecoder(decode.Options{})
|
||||
require.NoError(t, err)
|
||||
|
||||
decodeTx, err := decoder.Decode(txBytes)
|
||||
if tc.error != "" {
|
||||
require.EqualError(t, err, tc.error)
|
||||
@ -99,3 +109,13 @@ func TestDecode(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type dummyAddressCodec struct{}
|
||||
|
||||
func (d dummyAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return hex.DecodeString(text)
|
||||
}
|
||||
|
||||
func (d dummyAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return hex.EncodeToString(bz), nil
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "cosmos/msg/v1/msg.proto";
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
|
||||
option go_package = "cosmossdk.io/x/tx/internal/testpb";
|
||||
|
||||
@ -58,6 +59,12 @@ message BadSigner {
|
||||
option (cosmos.msg.v1.signer) = "signer";
|
||||
bytes signer = 1;
|
||||
}
|
||||
|
||||
message NoSignerOption {
|
||||
bytes signer = 1;
|
||||
}
|
||||
|
||||
message ValidatorSigner {
|
||||
option (cosmos.msg.v1.signer) = "signer";
|
||||
string signer = 1 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"];
|
||||
}
|
||||
@ -4,6 +4,7 @@ package testpb
|
||||
import (
|
||||
_ "cosmossdk.io/api/cosmos/msg/v1"
|
||||
fmt "fmt"
|
||||
_ "github.com/cosmos/cosmos-proto"
|
||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||
@ -1368,7 +1369,7 @@ func (x *NestedSigner_Inner) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
|
||||
func (x *NestedSigner_Inner) slowProtoReflect() protoreflect.Message {
|
||||
mi := &file_signers_proto_msgTypes[8]
|
||||
mi := &file_signers_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -2282,7 +2283,7 @@ func (x *RepeatedNestedSigner_Inner) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
|
||||
func (x *RepeatedNestedSigner_Inner) slowProtoReflect() protoreflect.Message {
|
||||
mi := &file_signers_proto_msgTypes[9]
|
||||
mi := &file_signers_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -3183,7 +3184,7 @@ func (x *NestedRepeatedSigner_Inner) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
|
||||
func (x *NestedRepeatedSigner_Inner) slowProtoReflect() protoreflect.Message {
|
||||
mi := &file_signers_proto_msgTypes[10]
|
||||
mi := &file_signers_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -4157,7 +4158,7 @@ func (x *RepeatedNestedRepeatedSigner_Inner) ProtoReflect() protoreflect.Message
|
||||
}
|
||||
|
||||
func (x *RepeatedNestedRepeatedSigner_Inner) slowProtoReflect() protoreflect.Message {
|
||||
mi := &file_signers_proto_msgTypes[11]
|
||||
mi := &file_signers_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -5415,6 +5416,426 @@ func (x *fastReflection_NoSignerOption) ProtoMethods() *protoiface.Methods {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
md_ValidatorSigner protoreflect.MessageDescriptor
|
||||
fd_ValidatorSigner_signer protoreflect.FieldDescriptor
|
||||
)
|
||||
|
||||
func init() {
|
||||
file_signers_proto_init()
|
||||
md_ValidatorSigner = File_signers_proto.Messages().ByName("ValidatorSigner")
|
||||
fd_ValidatorSigner_signer = md_ValidatorSigner.Fields().ByName("signer")
|
||||
}
|
||||
|
||||
var _ protoreflect.Message = (*fastReflection_ValidatorSigner)(nil)
|
||||
|
||||
type fastReflection_ValidatorSigner ValidatorSigner
|
||||
|
||||
func (x *ValidatorSigner) ProtoReflect() protoreflect.Message {
|
||||
return (*fastReflection_ValidatorSigner)(x)
|
||||
}
|
||||
|
||||
func (x *ValidatorSigner) slowProtoReflect() protoreflect.Message {
|
||||
mi := &file_signers_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
var _fastReflection_ValidatorSigner_messageType fastReflection_ValidatorSigner_messageType
|
||||
var _ protoreflect.MessageType = fastReflection_ValidatorSigner_messageType{}
|
||||
|
||||
type fastReflection_ValidatorSigner_messageType struct{}
|
||||
|
||||
func (x fastReflection_ValidatorSigner_messageType) Zero() protoreflect.Message {
|
||||
return (*fastReflection_ValidatorSigner)(nil)
|
||||
}
|
||||
func (x fastReflection_ValidatorSigner_messageType) New() protoreflect.Message {
|
||||
return new(fastReflection_ValidatorSigner)
|
||||
}
|
||||
func (x fastReflection_ValidatorSigner_messageType) Descriptor() protoreflect.MessageDescriptor {
|
||||
return md_ValidatorSigner
|
||||
}
|
||||
|
||||
// Descriptor returns message descriptor, which contains only the protobuf
|
||||
// type information for the message.
|
||||
func (x *fastReflection_ValidatorSigner) Descriptor() protoreflect.MessageDescriptor {
|
||||
return md_ValidatorSigner
|
||||
}
|
||||
|
||||
// Type returns the message type, which encapsulates both Go and protobuf
|
||||
// type information. If the Go type information is not needed,
|
||||
// it is recommended that the message descriptor be used instead.
|
||||
func (x *fastReflection_ValidatorSigner) Type() protoreflect.MessageType {
|
||||
return _fastReflection_ValidatorSigner_messageType
|
||||
}
|
||||
|
||||
// New returns a newly allocated and mutable empty message.
|
||||
func (x *fastReflection_ValidatorSigner) New() protoreflect.Message {
|
||||
return new(fastReflection_ValidatorSigner)
|
||||
}
|
||||
|
||||
// Interface unwraps the message reflection interface and
|
||||
// returns the underlying ProtoMessage interface.
|
||||
func (x *fastReflection_ValidatorSigner) Interface() protoreflect.ProtoMessage {
|
||||
return (*ValidatorSigner)(x)
|
||||
}
|
||||
|
||||
// Range iterates over every populated field in an undefined order,
|
||||
// calling f for each field descriptor and value encountered.
|
||||
// Range returns immediately if f returns false.
|
||||
// While iterating, mutating operations may only be performed
|
||||
// on the current field descriptor.
|
||||
func (x *fastReflection_ValidatorSigner) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
|
||||
if x.Signer != "" {
|
||||
value := protoreflect.ValueOfString(x.Signer)
|
||||
if !f(fd_ValidatorSigner_signer, value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Has reports whether a field is populated.
|
||||
//
|
||||
// Some fields have the property of nullability where it is possible to
|
||||
// distinguish between the default value of a field and whether the field
|
||||
// was explicitly populated with the default value. Singular message fields,
|
||||
// member fields of a oneof, and proto2 scalar fields are nullable. Such
|
||||
// fields are populated only if explicitly set.
|
||||
//
|
||||
// In other cases (aside from the nullable cases above),
|
||||
// a proto3 scalar field is populated if it contains a non-zero value, and
|
||||
// a repeated field is populated if it is non-empty.
|
||||
func (x *fastReflection_ValidatorSigner) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
switch fd.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
return x.Signer != ""
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Clear clears the field such that a subsequent Has call reports false.
|
||||
//
|
||||
// Clearing an extension field clears both the extension type and value
|
||||
// associated with the given field number.
|
||||
//
|
||||
// Clear is a mutating operation and unsafe for concurrent use.
|
||||
func (x *fastReflection_ValidatorSigner) Clear(fd protoreflect.FieldDescriptor) {
|
||||
switch fd.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
x.Signer = ""
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves the value for a field.
|
||||
//
|
||||
// For unpopulated scalars, it returns the default value, where
|
||||
// the default value of a bytes scalar is guaranteed to be a copy.
|
||||
// For unpopulated composite types, it returns an empty, read-only view
|
||||
// of the value; to obtain a mutable reference, use Mutable.
|
||||
func (x *fastReflection_ValidatorSigner) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
switch descriptor.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
value := x.Signer
|
||||
return protoreflect.ValueOfString(value)
|
||||
default:
|
||||
if descriptor.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", descriptor.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Set stores the value for a field.
|
||||
//
|
||||
// For a field belonging to a oneof, it implicitly clears any other field
|
||||
// that may be currently set within the same oneof.
|
||||
// For extension fields, it implicitly stores the provided ExtensionType.
|
||||
// When setting a composite type, it is unspecified whether the stored value
|
||||
// aliases the source's memory in any way. If the composite value is an
|
||||
// empty, read-only value, then it panics.
|
||||
//
|
||||
// Set is a mutating operation and unsafe for concurrent use.
|
||||
func (x *fastReflection_ValidatorSigner) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) {
|
||||
switch fd.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
x.Signer = value.Interface().(string)
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Mutable returns a mutable reference to a composite type.
|
||||
//
|
||||
// If the field is unpopulated, it may allocate a composite value.
|
||||
// For a field belonging to a oneof, it implicitly clears any other field
|
||||
// that may be currently set within the same oneof.
|
||||
// For extension fields, it implicitly stores the provided ExtensionType
|
||||
// if not already stored.
|
||||
// It panics if the field does not contain a composite type.
|
||||
//
|
||||
// Mutable is a mutating operation and unsafe for concurrent use.
|
||||
func (x *fastReflection_ValidatorSigner) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
switch fd.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
panic(fmt.Errorf("field signer of message ValidatorSigner is not mutable"))
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// NewField returns a new value that is assignable to the field
|
||||
// for the given descriptor. For scalars, this returns the default value.
|
||||
// For lists, maps, and messages, this returns a new, empty, mutable value.
|
||||
func (x *fastReflection_ValidatorSigner) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
switch fd.FullName() {
|
||||
case "ValidatorSigner.signer":
|
||||
return protoreflect.ValueOfString("")
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: ValidatorSigner"))
|
||||
}
|
||||
panic(fmt.Errorf("message ValidatorSigner does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
// WhichOneof reports which field within the oneof is populated,
|
||||
// returning nil if none are populated.
|
||||
// It panics if the oneof descriptor does not belong to this message.
|
||||
func (x *fastReflection_ValidatorSigner) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
switch d.FullName() {
|
||||
default:
|
||||
panic(fmt.Errorf("%s is not a oneof field in ValidatorSigner", d.FullName()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// GetUnknown retrieves the entire list of unknown fields.
|
||||
// The caller may only mutate the contents of the RawFields
|
||||
// if the mutated bytes are stored back into the message with SetUnknown.
|
||||
func (x *fastReflection_ValidatorSigner) GetUnknown() protoreflect.RawFields {
|
||||
return x.unknownFields
|
||||
}
|
||||
|
||||
// SetUnknown stores an entire list of unknown fields.
|
||||
// The raw fields must be syntactically valid according to the wire format.
|
||||
// An implementation may panic if this is not the case.
|
||||
// Once stored, the caller must not mutate the content of the RawFields.
|
||||
// An empty RawFields may be passed to clear the fields.
|
||||
//
|
||||
// SetUnknown is a mutating operation and unsafe for concurrent use.
|
||||
func (x *fastReflection_ValidatorSigner) SetUnknown(fields protoreflect.RawFields) {
|
||||
x.unknownFields = fields
|
||||
}
|
||||
|
||||
// IsValid reports whether the message is valid.
|
||||
//
|
||||
// An invalid message is an empty, read-only value.
|
||||
//
|
||||
// An invalid message often corresponds to a nil pointer of the concrete
|
||||
// message type, but the details are implementation dependent.
|
||||
// Validity is not part of the protobuf data model, and may not
|
||||
// be preserved in marshaling or other operations.
|
||||
func (x *fastReflection_ValidatorSigner) IsValid() bool {
|
||||
return x != nil
|
||||
}
|
||||
|
||||
// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations.
|
||||
// This method may return nil.
|
||||
//
|
||||
// The returned methods type is identical to
|
||||
// "google.golang.org/protobuf/runtime/protoiface".Methods.
|
||||
// Consult the protoiface package documentation for details.
|
||||
func (x *fastReflection_ValidatorSigner) ProtoMethods() *protoiface.Methods {
|
||||
size := func(input protoiface.SizeInput) protoiface.SizeOutput {
|
||||
x := input.Message.Interface().(*ValidatorSigner)
|
||||
if x == nil {
|
||||
return protoiface.SizeOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Size: 0,
|
||||
}
|
||||
}
|
||||
options := runtime.SizeInputToOptions(input)
|
||||
_ = options
|
||||
var n int
|
||||
var l int
|
||||
_ = l
|
||||
l = len(x.Signer)
|
||||
if l > 0 {
|
||||
n += 1 + l + runtime.Sov(uint64(l))
|
||||
}
|
||||
if x.unknownFields != nil {
|
||||
n += len(x.unknownFields)
|
||||
}
|
||||
return protoiface.SizeOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Size: n,
|
||||
}
|
||||
}
|
||||
|
||||
marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
|
||||
x := input.Message.Interface().(*ValidatorSigner)
|
||||
if x == nil {
|
||||
return protoiface.MarshalOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Buf: input.Buf,
|
||||
}, nil
|
||||
}
|
||||
options := runtime.MarshalInputToOptions(input)
|
||||
_ = options
|
||||
size := options.Size(x)
|
||||
dAtA := make([]byte, size)
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if x.unknownFields != nil {
|
||||
i -= len(x.unknownFields)
|
||||
copy(dAtA[i:], x.unknownFields)
|
||||
}
|
||||
if len(x.Signer) > 0 {
|
||||
i -= len(x.Signer)
|
||||
copy(dAtA[i:], x.Signer)
|
||||
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Signer)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
if input.Buf != nil {
|
||||
input.Buf = append(input.Buf, dAtA...)
|
||||
} else {
|
||||
input.Buf = dAtA
|
||||
}
|
||||
return protoiface.MarshalOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Buf: input.Buf,
|
||||
}, nil
|
||||
}
|
||||
unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
|
||||
x := input.Message.Interface().(*ValidatorSigner)
|
||||
if x == nil {
|
||||
return protoiface.UnmarshalOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Flags: input.Flags,
|
||||
}, nil
|
||||
}
|
||||
options := runtime.UnmarshalInputToOptions(input)
|
||||
_ = options
|
||||
dAtA := input.Buf
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ValidatorSigner: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ValidatorSigner: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
x.Signer = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := runtime.Skip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
if !options.DiscardUnknown {
|
||||
x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil
|
||||
}
|
||||
return &protoiface.Methods{
|
||||
NoUnkeyedLiterals: struct{}{},
|
||||
Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown,
|
||||
Size: size,
|
||||
Marshal: marshal,
|
||||
Unmarshal: unmarshal,
|
||||
Merge: nil,
|
||||
CheckInitialized: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.0
|
||||
@ -5708,6 +6129,41 @@ func (x *NoSignerOption) GetSigner() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ValidatorSigner struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ValidatorSigner) Reset() {
|
||||
*x = ValidatorSigner{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_signers_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ValidatorSigner) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ValidatorSigner) ProtoMessage() {}
|
||||
|
||||
// Deprecated: Use ValidatorSigner.ProtoReflect.Descriptor instead.
|
||||
func (*ValidatorSigner) Descriptor() ([]byte, []int) {
|
||||
return file_signers_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *ValidatorSigner) GetSigner() string {
|
||||
if x != nil {
|
||||
return x.Signer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type NestedSigner_Inner struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -5719,7 +6175,7 @@ type NestedSigner_Inner struct {
|
||||
func (x *NestedSigner_Inner) Reset() {
|
||||
*x = NestedSigner_Inner{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_signers_proto_msgTypes[8]
|
||||
mi := &file_signers_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -5754,7 +6210,7 @@ type RepeatedNestedSigner_Inner struct {
|
||||
func (x *RepeatedNestedSigner_Inner) Reset() {
|
||||
*x = RepeatedNestedSigner_Inner{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_signers_proto_msgTypes[9]
|
||||
mi := &file_signers_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -5789,7 +6245,7 @@ type NestedRepeatedSigner_Inner struct {
|
||||
func (x *NestedRepeatedSigner_Inner) Reset() {
|
||||
*x = NestedRepeatedSigner_Inner{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_signers_proto_msgTypes[10]
|
||||
mi := &file_signers_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -5824,7 +6280,7 @@ type RepeatedNestedRepeatedSigner_Inner struct {
|
||||
func (x *RepeatedNestedRepeatedSigner_Inner) Reset() {
|
||||
*x = RepeatedNestedRepeatedSigner_Inner{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_signers_proto_msgTypes[11]
|
||||
mi := &file_signers_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -5853,57 +6309,65 @@ var File_signers_proto protoreflect.FileDescriptor
|
||||
var file_signers_proto_rawDesc = []byte{
|
||||
0x0a, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||
0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d,
|
||||
0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x0c, 0x53, 0x69, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x35, 0x0a,
|
||||
0x0e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12,
|
||||
0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x0c, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0,
|
||||
0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65,
|
||||
0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22,
|
||||
0x73, 0x0a, 0x0c, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12,
|
||||
0x29, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
|
||||
0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6e,
|
||||
0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0x2c, 0x0a, 0x05, 0x49, 0x6e,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0,
|
||||
0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69,
|
||||
0x6e, 0x6e, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65,
|
||||
0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x31, 0x0a,
|
||||
0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x52,
|
||||
0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72,
|
||||
0x1a, 0x2c, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65,
|
||||
0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a,
|
||||
0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x4e,
|
||||
0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52,
|
||||
0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0x2c, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x22, 0x73, 0x0a, 0x0c, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a,
|
||||
0x2c, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82,
|
||||
0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x52, 0x65,
|
||||
0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x1b, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74,
|
||||
0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05,
|
||||
0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0x2c, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22,
|
||||
0x83, 0x01, 0x0a, 0x14, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64,
|
||||
0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e, 0x49,
|
||||
0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0x2c, 0x0a, 0x05, 0x49,
|
||||
0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7,
|
||||
0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05,
|
||||
0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65,
|
||||
0x72, 0x1a, 0x2c, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a,
|
||||
0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x09, 0x42,
|
||||
0x61, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x28, 0x0a,
|
||||
0x0e, 0x4e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x42, 0x3b, 0x42, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x65,
|
||||
0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x74, 0x78, 0x2f, 0x74, 0x65, 0x78,
|
||||
0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65,
|
||||
0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72,
|
||||
0x22, 0x93, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73,
|
||||
0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65,
|
||||
0x72, 0x12, 0x39, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x23, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65,
|
||||
0x64, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e,
|
||||
0x49, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x1a, 0x2c, 0x0a, 0x05,
|
||||
0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82,
|
||||
0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a,
|
||||
0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x09, 0x42, 0x61, 0x64, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0,
|
||||
0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x0e, 0x4e, 0x6f, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x22, 0x59, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x42, 0x3b, 0x42,
|
||||
0x0c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x29, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f,
|
||||
0x74, 0x78, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -5918,7 +6382,7 @@ func file_signers_proto_rawDescGZIP() []byte {
|
||||
return file_signers_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_signers_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_signers_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
|
||||
var file_signers_proto_goTypes = []interface{}{
|
||||
(*SimpleSigner)(nil), // 0: SimpleSigner
|
||||
(*RepeatedSigner)(nil), // 1: RepeatedSigner
|
||||
@ -5928,16 +6392,17 @@ var file_signers_proto_goTypes = []interface{}{
|
||||
(*RepeatedNestedRepeatedSigner)(nil), // 5: RepeatedNestedRepeatedSigner
|
||||
(*BadSigner)(nil), // 6: BadSigner
|
||||
(*NoSignerOption)(nil), // 7: NoSignerOption
|
||||
(*NestedSigner_Inner)(nil), // 8: NestedSigner.Inner
|
||||
(*RepeatedNestedSigner_Inner)(nil), // 9: RepeatedNestedSigner.Inner
|
||||
(*NestedRepeatedSigner_Inner)(nil), // 10: NestedRepeatedSigner.Inner
|
||||
(*RepeatedNestedRepeatedSigner_Inner)(nil), // 11: RepeatedNestedRepeatedSigner.Inner
|
||||
(*ValidatorSigner)(nil), // 8: ValidatorSigner
|
||||
(*NestedSigner_Inner)(nil), // 9: NestedSigner.Inner
|
||||
(*RepeatedNestedSigner_Inner)(nil), // 10: RepeatedNestedSigner.Inner
|
||||
(*NestedRepeatedSigner_Inner)(nil), // 11: NestedRepeatedSigner.Inner
|
||||
(*RepeatedNestedRepeatedSigner_Inner)(nil), // 12: RepeatedNestedRepeatedSigner.Inner
|
||||
}
|
||||
var file_signers_proto_depIdxs = []int32{
|
||||
8, // 0: NestedSigner.inner:type_name -> NestedSigner.Inner
|
||||
9, // 1: RepeatedNestedSigner.inner:type_name -> RepeatedNestedSigner.Inner
|
||||
10, // 2: NestedRepeatedSigner.inner:type_name -> NestedRepeatedSigner.Inner
|
||||
11, // 3: RepeatedNestedRepeatedSigner.inner:type_name -> RepeatedNestedRepeatedSigner.Inner
|
||||
9, // 0: NestedSigner.inner:type_name -> NestedSigner.Inner
|
||||
10, // 1: RepeatedNestedSigner.inner:type_name -> RepeatedNestedSigner.Inner
|
||||
11, // 2: NestedRepeatedSigner.inner:type_name -> NestedRepeatedSigner.Inner
|
||||
12, // 3: RepeatedNestedRepeatedSigner.inner:type_name -> RepeatedNestedRepeatedSigner.Inner
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
@ -6048,7 +6513,7 @@ func file_signers_proto_init() {
|
||||
}
|
||||
}
|
||||
file_signers_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NestedSigner_Inner); i {
|
||||
switch v := v.(*ValidatorSigner); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -6060,7 +6525,7 @@ func file_signers_proto_init() {
|
||||
}
|
||||
}
|
||||
file_signers_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RepeatedNestedSigner_Inner); i {
|
||||
switch v := v.(*NestedSigner_Inner); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -6072,7 +6537,7 @@ func file_signers_proto_init() {
|
||||
}
|
||||
}
|
||||
file_signers_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NestedRepeatedSigner_Inner); i {
|
||||
switch v := v.(*RepeatedNestedSigner_Inner); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -6084,6 +6549,18 @@ func file_signers_proto_init() {
|
||||
}
|
||||
}
|
||||
file_signers_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NestedRepeatedSigner_Inner); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_signers_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RepeatedNestedRepeatedSigner_Inner); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -6102,7 +6579,7 @@ func file_signers_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_signers_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 12,
|
||||
NumMessages: 13,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
320
x/tx/signing/context.go
Normal file
320
x/tx/signing/context.go
Normal file
@ -0,0 +1,320 @@
|
||||
package signing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
cosmos_proto "github.com/cosmos/cosmos-proto"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
|
||||
msgv1 "cosmossdk.io/api/cosmos/msg/v1"
|
||||
)
|
||||
|
||||
// Context is a context for retrieving the list of signers from a
|
||||
// message where signers are specified by the cosmos.msg.v1.signer protobuf
|
||||
// option. It also contains the ProtoFileResolver and address.Codec's used
|
||||
// for resolving message descriptors and converting addresses.
|
||||
type Context struct {
|
||||
fileResolver ProtoFileResolver
|
||||
typeResolver protoregistry.MessageTypeResolver
|
||||
addressCodec address.Codec
|
||||
validatorAddressCodec address.Codec
|
||||
getSignersFuncs map[protoreflect.FullName]getSignersFunc
|
||||
}
|
||||
|
||||
// Options are options for creating Context which will be used for signing operations.
|
||||
type Options struct {
|
||||
// FileResolver is the protobuf file resolver to use for resolving message descriptors.
|
||||
// If it is nil, the global protobuf registry will be used.
|
||||
FileResolver ProtoFileResolver
|
||||
|
||||
// TypeResolver is the protobuf type resolver to use for resolving message types.
|
||||
TypeResolver protoregistry.MessageTypeResolver
|
||||
|
||||
// AddressCodec is the codec for converting addresses between strings and bytes.
|
||||
AddressCodec address.Codec
|
||||
|
||||
// ValidatorAddressCodec is the codec for converting validator addresses between strings and bytes.
|
||||
ValidatorAddressCodec address.Codec
|
||||
}
|
||||
|
||||
// ProtoFileResolver is a protodesc.Resolver that also allows iterating over all
|
||||
// files descriptors. It is a subset of the methods supported by protoregistry.Files.
|
||||
type ProtoFileResolver interface {
|
||||
protodesc.Resolver
|
||||
RangeFiles(func(protoreflect.FileDescriptor) bool)
|
||||
}
|
||||
|
||||
// NewContext creates a new Context using the provided options.
|
||||
func NewContext(options Options) (*Context, error) {
|
||||
protoFiles := options.FileResolver
|
||||
if protoFiles == nil {
|
||||
protoFiles = protoregistry.GlobalFiles
|
||||
}
|
||||
|
||||
protoTypes := options.TypeResolver
|
||||
if protoTypes == nil {
|
||||
protoTypes = protoregistry.GlobalTypes
|
||||
}
|
||||
|
||||
if options.AddressCodec == nil {
|
||||
return nil, errors.New("address codec is required")
|
||||
}
|
||||
|
||||
if options.ValidatorAddressCodec == nil {
|
||||
return nil, errors.New("validator address codec is required")
|
||||
}
|
||||
|
||||
c := &Context{
|
||||
fileResolver: protoFiles,
|
||||
typeResolver: protoTypes,
|
||||
addressCodec: options.AddressCodec,
|
||||
validatorAddressCodec: options.ValidatorAddressCodec,
|
||||
getSignersFuncs: map[protoreflect.FullName]getSignersFunc{},
|
||||
}
|
||||
|
||||
return c, c.init()
|
||||
}
|
||||
|
||||
type getSignersFunc func(proto.Message) ([][]byte, error)
|
||||
|
||||
func getSignersFieldNames(descriptor protoreflect.MessageDescriptor) ([]string, error) {
|
||||
signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string)
|
||||
if len(signersFields) == 0 {
|
||||
return nil, fmt.Errorf("no cosmos.msg.v1.signer option found for message %s", descriptor.FullName())
|
||||
}
|
||||
|
||||
return signersFields, nil
|
||||
}
|
||||
|
||||
// init performs a dry run of getting all msg's signers. This has 2 benefits:
|
||||
// - it will error if any Msg has forgotten the "cosmos.msg.v1.signer"
|
||||
// annotation
|
||||
// - it will pre-populate the context's internal cache for getSignersFuncs
|
||||
// so that calling it in antehandlers will be faster.
|
||||
func (c *Context) init() error {
|
||||
var errs []error
|
||||
c.fileResolver.RangeFiles(func(fd protoreflect.FileDescriptor) bool {
|
||||
for i := 0; i < fd.Services().Len(); i++ {
|
||||
sd := fd.Services().Get(i)
|
||||
// We use the heuristic that services named "Msg" are exactly the
|
||||
// ones that need the proto annotation check.
|
||||
if sd.Name() != "Msg" {
|
||||
continue
|
||||
}
|
||||
|
||||
for j := 0; j < sd.Methods().Len(); j++ {
|
||||
md := sd.Methods().Get(j).Input()
|
||||
msg := dynamicpb.NewMessage(md)
|
||||
_, err := c.GetSigners(msg)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (c *Context) makeGetSignersFunc(descriptor protoreflect.MessageDescriptor) (getSignersFunc, error) {
|
||||
signersFields, err := getSignersFieldNames(descriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fieldGetters := make([]func(proto.Message, [][]byte) ([][]byte, error), len(signersFields))
|
||||
for i, fieldName := range signersFields {
|
||||
field := descriptor.Fields().ByName(protoreflect.Name(fieldName))
|
||||
if field == nil {
|
||||
return nil, fmt.Errorf("field %s not found in message %s", fieldName, descriptor.FullName())
|
||||
}
|
||||
|
||||
if field.IsMap() || field.HasOptionalKeyword() {
|
||||
return nil, fmt.Errorf("cosmos.msg.v1.signer field %s in message %s must not be a map or optional", fieldName, descriptor.FullName())
|
||||
}
|
||||
|
||||
switch field.Kind() {
|
||||
case protoreflect.StringKind:
|
||||
addrCdc := c.getAddressCodec(field)
|
||||
if field.IsList() {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
signers := msg.ProtoReflect().Get(field).List()
|
||||
n := signers.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
addrStr := signers.Get(i).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arr = append(arr, addrBz)
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
addrStr := msg.ProtoReflect().Get(field).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(arr, addrBz), nil
|
||||
}
|
||||
}
|
||||
case protoreflect.MessageKind:
|
||||
isList := field.IsList()
|
||||
nestedMessage := field.Message()
|
||||
nestedSignersFields, err := getSignersFieldNames(nestedMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(nestedSignersFields) != 1 {
|
||||
return nil, fmt.Errorf("nested cosmos.msg.v1.signer option in message %s must contain only one value", nestedMessage.FullName())
|
||||
}
|
||||
|
||||
nestedFieldName := nestedSignersFields[0]
|
||||
nestedField := nestedMessage.Fields().ByName(protoreflect.Name(nestedFieldName))
|
||||
nestedIsList := nestedField.IsList()
|
||||
if nestedField == nil {
|
||||
return nil, fmt.Errorf("field %s not found in message %s", nestedFieldName, nestedMessage.FullName())
|
||||
}
|
||||
|
||||
if nestedField.Kind() != protoreflect.StringKind || nestedField.IsMap() || nestedField.HasOptionalKeyword() {
|
||||
return nil, fmt.Errorf("nested signer field %s in message %s must be a simple string", nestedFieldName, nestedMessage.FullName())
|
||||
}
|
||||
|
||||
addrCdc := c.getAddressCodec(nestedField)
|
||||
|
||||
if isList {
|
||||
if nestedIsList {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
msgs := msg.ProtoReflect().Get(field).List()
|
||||
m := msgs.Len()
|
||||
for i := 0; i < m; i++ {
|
||||
signers := msgs.Get(i).Message().Get(nestedField).List()
|
||||
n := signers.Len()
|
||||
for j := 0; j < n; j++ {
|
||||
addrStr := signers.Get(j).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arr = append(arr, addrBz)
|
||||
}
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
msgs := msg.ProtoReflect().Get(field).List()
|
||||
m := msgs.Len()
|
||||
for i := 0; i < m; i++ {
|
||||
addrStr := msgs.Get(i).Message().Get(nestedField).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arr = append(arr, addrBz)
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if nestedIsList {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
nestedMsg := msg.ProtoReflect().Get(field).Message()
|
||||
signers := nestedMsg.Get(nestedField).List()
|
||||
n := signers.Len()
|
||||
for j := 0; j < n; j++ {
|
||||
addrStr := signers.Get(j).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arr = append(arr, addrBz)
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) {
|
||||
addrStr := msg.ProtoReflect().Get(field).Message().Get(nestedField).String()
|
||||
addrBz, err := addrCdc.StringToBytes(addrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(arr, addrBz), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected field type %s for field %s in message %s", field.Kind(), fieldName, descriptor.FullName())
|
||||
}
|
||||
}
|
||||
|
||||
return func(message proto.Message) ([][]byte, error) {
|
||||
var signers [][]byte
|
||||
for _, getter := range fieldGetters {
|
||||
signers, err = getter(message, signers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return signers, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Context) getAddressCodec(field protoreflect.FieldDescriptor) address.Codec {
|
||||
scalarOpt := proto.GetExtension(field.Options(), cosmos_proto.E_Scalar)
|
||||
addrCdc := c.addressCodec
|
||||
if scalarOpt != nil {
|
||||
if scalarOpt.(string) == "cosmos.ValidatorAddressString" {
|
||||
addrCdc = c.validatorAddressCodec
|
||||
}
|
||||
}
|
||||
|
||||
return addrCdc
|
||||
}
|
||||
|
||||
// GetSigners returns the signers for a given message.
|
||||
func (c *Context) GetSigners(msg proto.Message) ([][]byte, error) {
|
||||
messageDescriptor := msg.ProtoReflect().Descriptor()
|
||||
f, ok := c.getSignersFuncs[messageDescriptor.FullName()]
|
||||
if !ok {
|
||||
var err error
|
||||
f, err = c.makeGetSignersFunc(messageDescriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.getSignersFuncs[messageDescriptor.FullName()] = f
|
||||
}
|
||||
|
||||
return f(msg)
|
||||
}
|
||||
|
||||
// AddressCodec returns the address codec used by the context.
|
||||
func (c *Context) AddressCodec() address.Codec {
|
||||
return c.addressCodec
|
||||
}
|
||||
|
||||
// ValidatorAddressCodec returns the validator address codec used by the context.
|
||||
func (c *Context) ValidatorAddressCodec() address.Codec {
|
||||
return c.validatorAddressCodec
|
||||
}
|
||||
|
||||
// FileResolver returns the proto file resolver used by the context.
|
||||
func (c *Context) FileResolver() ProtoFileResolver {
|
||||
return c.fileResolver
|
||||
}
|
||||
|
||||
func (c *Context) TypeResolver() protoregistry.MessageTypeResolver {
|
||||
return c.typeResolver
|
||||
}
|
||||
170
x/tx/signing/context_test.go
Normal file
170
x/tx/signing/context_test.go
Normal file
@ -0,0 +1,170 @@
|
||||
package signing
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
groupv1 "cosmossdk.io/api/cosmos/group/v1"
|
||||
"cosmossdk.io/core/address"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"cosmossdk.io/x/tx/internal/testpb"
|
||||
)
|
||||
|
||||
func TestGetSigners(t *testing.T) {
|
||||
ctx, err := NewContext(Options{
|
||||
AddressCodec: dummyAddressCodec{},
|
||||
ValidatorAddressCodec: dummyValidatorAddressCodec{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
msg proto.Message
|
||||
want [][]byte
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "MsgSend",
|
||||
msg: &bankv1beta1.MsgSend{
|
||||
FromAddress: hex.EncodeToString([]byte("foo")),
|
||||
},
|
||||
want: [][]byte{[]byte("foo")},
|
||||
},
|
||||
{
|
||||
name: "MsgMultiSend",
|
||||
msg: &bankv1beta1.MsgMultiSend{
|
||||
Inputs: []*bankv1beta1.Input{
|
||||
{Address: hex.EncodeToString([]byte("foo"))},
|
||||
{Address: hex.EncodeToString([]byte("bar"))},
|
||||
},
|
||||
},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "MsgSubmitProposal",
|
||||
msg: &groupv1.MsgSubmitProposal{
|
||||
Proposers: []string{
|
||||
hex.EncodeToString([]byte("foo")),
|
||||
hex.EncodeToString([]byte("bar")),
|
||||
},
|
||||
},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
msg: &testpb.SimpleSigner{Signer: hex.EncodeToString([]byte("foo"))},
|
||||
want: [][]byte{[]byte("foo")},
|
||||
},
|
||||
{
|
||||
name: "repeated",
|
||||
msg: &testpb.RepeatedSigner{Signer: []string{
|
||||
hex.EncodeToString([]byte("foo")),
|
||||
hex.EncodeToString([]byte("bar")),
|
||||
}},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "nested",
|
||||
msg: &testpb.NestedSigner{Inner: &testpb.NestedSigner_Inner{Signer: hex.EncodeToString([]byte("foo"))}},
|
||||
want: [][]byte{[]byte("foo")},
|
||||
},
|
||||
{
|
||||
name: "nested repeated",
|
||||
msg: &testpb.NestedRepeatedSigner{Inner: &testpb.NestedRepeatedSigner_Inner{Signer: []string{
|
||||
hex.EncodeToString([]byte("foo")),
|
||||
hex.EncodeToString([]byte("bar")),
|
||||
}}},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "repeated nested",
|
||||
msg: &testpb.RepeatedNestedSigner{Inner: []*testpb.RepeatedNestedSigner_Inner{
|
||||
{Signer: hex.EncodeToString([]byte("foo"))},
|
||||
{Signer: hex.EncodeToString([]byte("bar"))},
|
||||
}},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "nested repeated",
|
||||
msg: &testpb.NestedRepeatedSigner{Inner: &testpb.NestedRepeatedSigner_Inner{
|
||||
Signer: []string{
|
||||
hex.EncodeToString([]byte("foo")),
|
||||
hex.EncodeToString([]byte("bar")),
|
||||
},
|
||||
}},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar")},
|
||||
},
|
||||
{
|
||||
name: "repeated nested repeated",
|
||||
msg: &testpb.RepeatedNestedRepeatedSigner{Inner: []*testpb.RepeatedNestedRepeatedSigner_Inner{
|
||||
{Signer: []string{
|
||||
hex.EncodeToString([]byte("foo")),
|
||||
hex.EncodeToString([]byte("bar")),
|
||||
}},
|
||||
{Signer: []string{
|
||||
hex.EncodeToString([]byte("baz")),
|
||||
hex.EncodeToString([]byte("bam")),
|
||||
}},
|
||||
{Signer: []string{
|
||||
hex.EncodeToString([]byte("blah")),
|
||||
}},
|
||||
}},
|
||||
want: [][]byte{[]byte("foo"), []byte("bar"), []byte("baz"), []byte("bam"), []byte("blah")},
|
||||
},
|
||||
{
|
||||
name: "bad",
|
||||
msg: &testpb.BadSigner{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no signer",
|
||||
msg: &testpb.NoSignerOption{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "validator signer",
|
||||
msg: &testpb.ValidatorSigner{
|
||||
Signer: "val" + hex.EncodeToString([]byte("foo")),
|
||||
},
|
||||
want: [][]byte{[]byte("foo")},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
signers, err := ctx.GetSigners(test.msg)
|
||||
if test.wantErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, test.want, signers)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type dummyAddressCodec struct{}
|
||||
|
||||
func (d dummyAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return hex.DecodeString(text)
|
||||
}
|
||||
|
||||
func (d dummyAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return hex.EncodeToString(bz), nil
|
||||
}
|
||||
|
||||
var _ address.Codec = dummyAddressCodec{}
|
||||
|
||||
type dummyValidatorAddressCodec struct{}
|
||||
|
||||
func (d dummyValidatorAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return hex.DecodeString(strings.TrimPrefix(text, "val"))
|
||||
}
|
||||
|
||||
func (d dummyValidatorAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return "val" + hex.EncodeToString(bz), nil
|
||||
}
|
||||
|
||||
var _ address.Codec = dummyValidatorAddressCodec{}
|
||||
@ -16,32 +16,30 @@ import (
|
||||
|
||||
// SignModeHandler is the SIGN_MODE_DIRECT_AUX implementation of signing.SignModeHandler.
|
||||
type SignModeHandler struct {
|
||||
signersContext *signing.GetSignersContext
|
||||
signersContext *signing.Context
|
||||
fileResolver signing.ProtoFileResolver
|
||||
typeResolver protoregistry.MessageTypeResolver
|
||||
}
|
||||
|
||||
// SignModeHandlerOptions are the options for the SignModeHandler.
|
||||
type SignModeHandlerOptions struct {
|
||||
// FileResolver is the protodesc.Resolver to use for resolving proto files when unpacking any messages.
|
||||
FileResolver signing.ProtoFileResolver
|
||||
|
||||
// TypeResolver is the protoregistry.MessageTypeResolver to use for resolving proto types when unpacking any messages.
|
||||
// TypeResolver is the protoregistry.MessageTypeResolver to use for resolving protobuf types when unpacking any messages.
|
||||
TypeResolver protoregistry.MessageTypeResolver
|
||||
|
||||
// SignersContext is the signing.GetSignersContext to use for getting signers.
|
||||
SignersContext *signing.GetSignersContext
|
||||
// SignersContext is the signing.Context to use for getting signers.
|
||||
SignersContext *signing.Context
|
||||
}
|
||||
|
||||
// NewSignModeHandler returns a new SignModeHandler.
|
||||
func NewSignModeHandler(options SignModeHandlerOptions) (SignModeHandler, error) {
|
||||
h := SignModeHandler{}
|
||||
|
||||
if options.FileResolver == nil {
|
||||
h.fileResolver = protoregistry.GlobalFiles
|
||||
} else {
|
||||
h.fileResolver = options.FileResolver
|
||||
if options.SignersContext == nil {
|
||||
return h, fmt.Errorf("signers context is required")
|
||||
}
|
||||
h.signersContext = options.SignersContext
|
||||
|
||||
h.fileResolver = h.signersContext.FileResolver()
|
||||
|
||||
if options.TypeResolver == nil {
|
||||
h.typeResolver = protoregistry.GlobalTypes
|
||||
@ -49,16 +47,6 @@ func NewSignModeHandler(options SignModeHandlerOptions) (SignModeHandler, error)
|
||||
h.typeResolver = options.TypeResolver
|
||||
}
|
||||
|
||||
if options.SignersContext == nil {
|
||||
var err error
|
||||
h.signersContext, err = signing.NewGetSignersContext(signing.GetSignersOptions{ProtoFiles: h.fileResolver})
|
||||
if err != nil {
|
||||
return h, err
|
||||
}
|
||||
} else {
|
||||
h.signersContext = options.SignersContext
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
@ -71,18 +59,18 @@ func (h SignModeHandler) Mode() signingv1beta1.SignMode {
|
||||
|
||||
// getFirstSigner returns the first signer from the first message in the tx. It replicates behavior in
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/4a6a1e3cb8de459891cb0495052589673d14ef51/x/auth/tx/builder.go#L142
|
||||
func (h SignModeHandler) getFirstSigner(txData signing.TxData) (string, error) {
|
||||
func (h SignModeHandler) getFirstSigner(txData signing.TxData) ([]byte, error) {
|
||||
if len(txData.Body.Messages) == 0 {
|
||||
return "", fmt.Errorf("no signer found")
|
||||
return nil, fmt.Errorf("no signer found")
|
||||
}
|
||||
|
||||
msg, err := anyutil.Unpack(txData.Body.Messages[0], h.fileResolver, h.typeResolver)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
signer, err := h.signersContext.GetSigners(msg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return signer[0], nil
|
||||
}
|
||||
@ -97,7 +85,10 @@ func (h SignModeHandler) GetSignBytes(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
feePayer = fp
|
||||
feePayer, err = h.signersContext.AddressCodec().BytesToString(fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if feePayer == signerData.Address {
|
||||
return nil, fmt.Errorf("fee payer %s cannot sign with %s: unauthorized",
|
||||
|
||||
@ -2,9 +2,11 @@ package directaux_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
"github.com/cosmos/cosmos-proto/anyutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@ -15,6 +17,7 @@ import (
|
||||
"cosmossdk.io/api/cosmos/crypto/secp256k1"
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
|
||||
|
||||
"cosmossdk.io/x/tx/signing"
|
||||
"cosmossdk.io/x/tx/signing/directaux"
|
||||
)
|
||||
@ -83,7 +86,14 @@ func TestDirectAuxHandler(t *testing.T) {
|
||||
AuthInfoBytes: authInfoBz,
|
||||
BodyBytes: bodyBz,
|
||||
}
|
||||
modeHandler, err := directaux.NewSignModeHandler(directaux.SignModeHandlerOptions{})
|
||||
signersCtx, err := signing.NewContext(signing.Options{
|
||||
AddressCodec: dummyAddressCodec{},
|
||||
ValidatorAddressCodec: dummyAddressCodec{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
modeHandler, err := directaux.NewSignModeHandler(directaux.SignModeHandlerOptions{
|
||||
SignersContext: signersCtx,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Log("verify fee payer cannot use SIGN_MODE_DIRECT_AUX")
|
||||
@ -143,3 +153,15 @@ func TestDirectAuxHandler(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, expectedSignBytes, signBytes)
|
||||
}
|
||||
|
||||
type dummyAddressCodec struct{}
|
||||
|
||||
func (d dummyAddressCodec) StringToBytes(text string) ([]byte, error) {
|
||||
return hex.DecodeString(text)
|
||||
}
|
||||
|
||||
func (d dummyAddressCodec) BytesToString(bz []byte) (string, error) {
|
||||
return hex.EncodeToString(bz), nil
|
||||
}
|
||||
|
||||
var _ address.Codec = dummyAddressCodec{}
|
||||
|
||||
@ -1,222 +0,0 @@
|
||||
package signing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
|
||||
msgv1 "cosmossdk.io/api/cosmos/msg/v1"
|
||||
)
|
||||
|
||||
// GetSignersContext is a context for retrieving the list of signers from a
|
||||
// message where signers are specified by the cosmos.msg.v1.signer protobuf
|
||||
// option.
|
||||
type GetSignersContext struct {
|
||||
protoFiles ProtoFileResolver
|
||||
getSignersFuncs map[protoreflect.FullName]getSignersFunc
|
||||
}
|
||||
|
||||
// GetSignersOptions are options for creating GetSignersContext.
|
||||
type GetSignersOptions struct {
|
||||
// ProtoFiles are the protobuf files to use for resolving message descriptors.
|
||||
// If it is nil, the global protobuf registry will be used.
|
||||
ProtoFiles ProtoFileResolver
|
||||
}
|
||||
|
||||
// ProtoFileResolver is a protodesc.Resolver that also allows iterating over all
|
||||
// files descriptors. It is a subset of the methods supported by protoregistry.Files.
|
||||
type ProtoFileResolver interface {
|
||||
protodesc.Resolver
|
||||
RangeFiles(func(protoreflect.FileDescriptor) bool)
|
||||
}
|
||||
|
||||
// NewGetSignersContext creates a new GetSignersContext using the provided options.
|
||||
func NewGetSignersContext(options GetSignersOptions) (*GetSignersContext, error) {
|
||||
protoFiles := options.ProtoFiles
|
||||
if protoFiles == nil {
|
||||
protoFiles = protoregistry.GlobalFiles
|
||||
}
|
||||
|
||||
c := &GetSignersContext{
|
||||
protoFiles: protoFiles,
|
||||
getSignersFuncs: map[protoreflect.FullName]getSignersFunc{},
|
||||
}
|
||||
|
||||
return c, c.init()
|
||||
}
|
||||
|
||||
type getSignersFunc func(proto.Message) []string
|
||||
|
||||
func getSignersFieldNames(descriptor protoreflect.MessageDescriptor) ([]string, error) {
|
||||
signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string)
|
||||
if len(signersFields) == 0 {
|
||||
return nil, fmt.Errorf("no cosmos.msg.v1.signer option found for message %s", descriptor.FullName())
|
||||
}
|
||||
|
||||
return signersFields, nil
|
||||
}
|
||||
|
||||
// init performs a dry run of getting all msg's signers. This has 2 benefits:
|
||||
// - it will error if any Msg has forgotten the "cosmos.msg.v1.signer"
|
||||
// annotation
|
||||
// - it will pre-populate the context's internal cache for getSignersFuncs
|
||||
// so that calling it in antehandlers will be faster.
|
||||
func (c *GetSignersContext) init() error {
|
||||
var errs []error
|
||||
c.protoFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool {
|
||||
for i := 0; i < fd.Services().Len(); i++ {
|
||||
sd := fd.Services().Get(i)
|
||||
// We use the heuristic that services named "Msg" are exactly the
|
||||
// ones that need the proto annotation check.
|
||||
if sd.Name() != "Msg" {
|
||||
continue
|
||||
}
|
||||
|
||||
for j := 0; j < sd.Methods().Len(); j++ {
|
||||
md := sd.Methods().Get(j).Input()
|
||||
msg := dynamicpb.NewMessage(md)
|
||||
_, err := c.GetSigners(msg)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (*GetSignersContext) makeGetSignersFunc(descriptor protoreflect.MessageDescriptor) (getSignersFunc, error) {
|
||||
signersFields, err := getSignersFieldNames(descriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fieldGetters := make([]func(proto.Message, []string) []string, len(signersFields))
|
||||
for i, fieldName := range signersFields {
|
||||
field := descriptor.Fields().ByName(protoreflect.Name(fieldName))
|
||||
if field == nil {
|
||||
return nil, fmt.Errorf("field %s not found in message %s", fieldName, descriptor.FullName())
|
||||
}
|
||||
|
||||
if field.IsMap() || field.HasOptionalKeyword() {
|
||||
return nil, fmt.Errorf("cosmos.msg.v1.signer field %s in message %s must not be a map or optional", fieldName, descriptor.FullName())
|
||||
}
|
||||
|
||||
switch field.Kind() {
|
||||
case protoreflect.StringKind:
|
||||
if field.IsList() {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
signers := msg.ProtoReflect().Get(field).List()
|
||||
n := signers.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
arr = append(arr, signers.Get(i).String())
|
||||
}
|
||||
return arr
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
return append(arr, msg.ProtoReflect().Get(field).String())
|
||||
}
|
||||
}
|
||||
case protoreflect.MessageKind:
|
||||
isList := field.IsList()
|
||||
nestedMessage := field.Message()
|
||||
nestedSignersFields, err := getSignersFieldNames(nestedMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(nestedSignersFields) != 1 {
|
||||
return nil, fmt.Errorf("nested cosmos.msg.v1.signer option in message %s must contain only one value", nestedMessage.FullName())
|
||||
}
|
||||
|
||||
nestedFieldName := nestedSignersFields[0]
|
||||
nestedField := nestedMessage.Fields().ByName(protoreflect.Name(nestedFieldName))
|
||||
nestedIsList := nestedField.IsList()
|
||||
if nestedField == nil {
|
||||
return nil, fmt.Errorf("field %s not found in message %s", nestedFieldName, nestedMessage.FullName())
|
||||
}
|
||||
|
||||
if nestedField.Kind() != protoreflect.StringKind || nestedField.IsMap() || nestedField.HasOptionalKeyword() {
|
||||
return nil, fmt.Errorf("nested signer field %s in message %s must be a simple string", nestedFieldName, nestedMessage.FullName())
|
||||
}
|
||||
|
||||
if isList {
|
||||
if nestedIsList {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
msgs := msg.ProtoReflect().Get(field).List()
|
||||
m := msgs.Len()
|
||||
for i := 0; i < m; i++ {
|
||||
signers := msgs.Get(i).Message().Get(nestedField).List()
|
||||
n := signers.Len()
|
||||
for j := 0; j < n; j++ {
|
||||
arr = append(arr, signers.Get(j).String())
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
msgs := msg.ProtoReflect().Get(field).List()
|
||||
m := msgs.Len()
|
||||
for i := 0; i < m; i++ {
|
||||
arr = append(arr, msgs.Get(i).Message().Get(nestedField).String())
|
||||
}
|
||||
return arr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if nestedIsList {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
nestedMsg := msg.ProtoReflect().Get(field).Message()
|
||||
signers := nestedMsg.Get(nestedField).List()
|
||||
n := signers.Len()
|
||||
for j := 0; j < n; j++ {
|
||||
arr = append(arr, signers.Get(j).String())
|
||||
}
|
||||
return arr
|
||||
}
|
||||
} else {
|
||||
fieldGetters[i] = func(msg proto.Message, arr []string) []string {
|
||||
return append(arr, msg.ProtoReflect().Get(field).Message().Get(nestedField).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected field type %s for field %s in message %s", field.Kind(), fieldName, descriptor.FullName())
|
||||
}
|
||||
}
|
||||
|
||||
return func(message proto.Message) []string {
|
||||
var signers []string
|
||||
for _, getter := range fieldGetters {
|
||||
signers = getter(message, signers)
|
||||
}
|
||||
return signers
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetSigners returns the signers for a given message.
|
||||
func (c *GetSignersContext) GetSigners(msg proto.Message) ([]string, error) {
|
||||
messageDescriptor := msg.ProtoReflect().Descriptor()
|
||||
f, ok := c.getSignersFuncs[messageDescriptor.FullName()]
|
||||
if !ok {
|
||||
var err error
|
||||
f, err = c.makeGetSignersFunc(messageDescriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.getSignersFuncs[messageDescriptor.FullName()] = f
|
||||
}
|
||||
|
||||
return f(msg), nil
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
package signing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
groupv1 "cosmossdk.io/api/cosmos/group/v1"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"cosmossdk.io/x/tx/internal/testpb"
|
||||
)
|
||||
|
||||
func TestGetSigners(t *testing.T) {
|
||||
ctx, err := NewGetSignersContext(GetSignersOptions{})
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
msg proto.Message
|
||||
want []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "MsgSend",
|
||||
msg: &bankv1beta1.MsgSend{
|
||||
FromAddress: "foo",
|
||||
},
|
||||
want: []string{"foo"},
|
||||
},
|
||||
{
|
||||
name: "MsgMultiSend",
|
||||
msg: &bankv1beta1.MsgMultiSend{
|
||||
Inputs: []*bankv1beta1.Input{
|
||||
{Address: "foo"},
|
||||
{Address: "bar"},
|
||||
},
|
||||
},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "MsgSubmitProposal",
|
||||
msg: &groupv1.MsgSubmitProposal{
|
||||
Proposers: []string{"foo", "bar"},
|
||||
},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
msg: &testpb.SimpleSigner{Signer: "foo"},
|
||||
want: []string{"foo"},
|
||||
},
|
||||
{
|
||||
name: "repeated",
|
||||
msg: &testpb.RepeatedSigner{Signer: []string{"foo", "bar"}},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "nested",
|
||||
msg: &testpb.NestedSigner{Inner: &testpb.NestedSigner_Inner{Signer: "foo"}},
|
||||
want: []string{"foo"},
|
||||
},
|
||||
{
|
||||
name: "nested repeated",
|
||||
msg: &testpb.NestedRepeatedSigner{Inner: &testpb.NestedRepeatedSigner_Inner{Signer: []string{"foo", "bar"}}},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "repeated nested",
|
||||
msg: &testpb.RepeatedNestedSigner{Inner: []*testpb.RepeatedNestedSigner_Inner{
|
||||
{Signer: "foo"},
|
||||
{Signer: "bar"},
|
||||
}},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "nested repeated",
|
||||
msg: &testpb.NestedRepeatedSigner{Inner: &testpb.NestedRepeatedSigner_Inner{
|
||||
Signer: []string{"foo", "bar"},
|
||||
}},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
name: "repeated nested repeated",
|
||||
msg: &testpb.RepeatedNestedRepeatedSigner{Inner: []*testpb.RepeatedNestedRepeatedSigner_Inner{
|
||||
{Signer: []string{"foo", "bar"}},
|
||||
{Signer: []string{"baz", "bam"}},
|
||||
{Signer: []string{"blah"}},
|
||||
}},
|
||||
want: []string{"foo", "bar", "baz", "bam", "blah"},
|
||||
},
|
||||
{
|
||||
name: "bad",
|
||||
msg: &testpb.BadSigner{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no signer",
|
||||
msg: &testpb.NoSignerOption{},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
signers, err := ctx.GetSigners(test.msg)
|
||||
if test.wantErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, test.want, signers)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user