From 1815981b021920850dcc04bcebcce1be56de13d8 Mon Sep 17 00:00:00 2001 From: likhita-809 <78951027+likhita-809@users.noreply.github.com> Date: Mon, 11 Jul 2022 22:46:27 +0530 Subject: [PATCH] feat: deprecate x/params usage in x/auth (#12475) * generate proto files * wip * wip: fix tests * wip: add tests * fix tests * fix tests * add changelog * address review comments * address review comments * add err check for setparams * updates Co-authored-by: Aleksandr Bezobchuk Co-authored-by: Aleksandr Bezobchuk --- CHANGELOG.md | 1 + api/cosmos/auth/v1beta1/genesis.pulsar.go | 2 +- api/cosmos/auth/v1beta1/tx.pulsar.go | 1091 +++++++++++++++++++++ api/cosmos/auth/v1beta1/tx_grpc.pb.go | 113 +++ baseapp/block_gas_test.go | 2 +- contrib/rosetta/rosetta-ci/data.tar.gz | Bin 43673 -> 43328 bytes proto/cosmos/auth/v1beta1/genesis.proto | 2 +- proto/cosmos/auth/v1beta1/tx.proto | 39 + simapp/app.go | 2 +- x/auth/ante/ante_test.go | 8 +- x/auth/ante/sigverify_test.go | 3 +- x/auth/ante/testutil_test.go | 3 +- x/auth/exported/exported.go | 18 + x/auth/keeper/account.go | 14 +- x/auth/keeper/genesis.go | 4 +- x/auth/keeper/grpc_query.go | 2 +- x/auth/keeper/keeper.go | 39 +- x/auth/keeper/keeper_test.go | 5 +- x/auth/keeper/migrations.go | 23 +- x/auth/keeper/msg_server.go | 36 + x/auth/keeper/msg_server_test.go | 111 +++ x/auth/keeper/params.go | 21 +- x/auth/keeper/params_test.go | 92 ++ x/auth/migrations/v043/store_test.go | 44 +- x/auth/migrations/v046/store_test.go | 41 +- x/auth/migrations/v2/migrate.go | 35 + x/auth/migrations/v2/migrator_test.go | 46 + x/auth/module.go | 43 +- x/auth/types/codec.go | 8 + x/auth/types/genesis.pb.go | 2 +- x/auth/types/keys.go | 3 + x/auth/types/msgs.go | 32 + x/auth/types/params.go | 30 - x/auth/types/params_legacy.go | 40 + x/auth/types/tx.pb.go | 603 ++++++++++++ x/bank/keeper/keeper_test.go | 15 +- 36 files changed, 2462 insertions(+), 111 deletions(-) create mode 100644 api/cosmos/auth/v1beta1/tx.pulsar.go create mode 100644 api/cosmos/auth/v1beta1/tx_grpc.pb.go create mode 100644 proto/cosmos/auth/v1beta1/tx.proto create mode 100644 x/auth/exported/exported.go create mode 100644 x/auth/keeper/msg_server.go create mode 100644 x/auth/keeper/msg_server_test.go create mode 100644 x/auth/keeper/params_test.go create mode 100644 x/auth/migrations/v2/migrate.go create mode 100644 x/auth/migrations/v2/migrator_test.go create mode 100644 x/auth/types/msgs.go create mode 100644 x/auth/types/params_legacy.go create mode 100644 x/auth/types/tx.pb.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b561e6c90..06e9ee46bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking +* (x/auth) [#12475](https://github.com/cosmos/cosmos-sdk/pull/12475) Migrate `x/auth` to self-managed parameters and deprecate its usage of `x/params`. * (x/slashing) [#12399](https://github.com/cosmos/cosmos-sdk/pull/12399) Migrate `x/slashing` to self-managed parameters and deprecate its usage of `x/params`. * (x/mint) [#12363](https://github.com/cosmos/cosmos-sdk/pull/12363) Migrate `x/mint` to self-managed parameters and deprecate it's usage of `x/params`. * (x/distribution) [#12434](https://github.com/cosmos/cosmos-sdk/pull/12434) Migrate `x/distribution` to self-managed parameters and deprecate it's usage of `x/params`. diff --git a/api/cosmos/auth/v1beta1/genesis.pulsar.go b/api/cosmos/auth/v1beta1/genesis.pulsar.go index 9f4af0ae4f..9aa36a1484 100644 --- a/api/cosmos/auth/v1beta1/genesis.pulsar.go +++ b/api/cosmos/auth/v1beta1/genesis.pulsar.go @@ -606,7 +606,7 @@ type GenesisState struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // params defines all the paramaters of the module. + // params defines all the parameters of the module. Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` // accounts are the accounts present at genesis. Accounts []*anypb.Any `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts,omitempty"` diff --git a/api/cosmos/auth/v1beta1/tx.pulsar.go b/api/cosmos/auth/v1beta1/tx.pulsar.go new file mode 100644 index 0000000000..b937cca783 --- /dev/null +++ b/api/cosmos/auth/v1beta1/tx.pulsar.go @@ -0,0 +1,1091 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package authv1beta1 + +import ( + _ "cosmossdk.io/api/cosmos/msg/v1" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/gogo/protobuf/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_MsgUpdateParams protoreflect.MessageDescriptor + fd_MsgUpdateParams_authority protoreflect.FieldDescriptor + fd_MsgUpdateParams_params protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_auth_v1beta1_tx_proto_init() + md_MsgUpdateParams = File_cosmos_auth_v1beta1_tx_proto.Messages().ByName("MsgUpdateParams") + fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") + fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) + +type fastReflection_MsgUpdateParams MsgUpdateParams + +func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(x) +} + +func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_auth_v1beta1_tx_proto_msgTypes[0] + 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_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} + +type fastReflection_MsgUpdateParams_messageType struct{} + +func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(nil) +} +func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} +func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// 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_MsgUpdateParams) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParams)(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_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgUpdateParams_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgUpdateParams_params, 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_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + return x.Authority != "" + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + x.Authority = "" + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message cosmos.auth.v1beta1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.auth.v1beta1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "cosmos.auth.v1beta1.MsgUpdateParams.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParams 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_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.auth.v1beta1.MsgUpdateParams", 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_MsgUpdateParams) 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_MsgUpdateParams) 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_MsgUpdateParams) 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_MsgUpdateParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParams) + 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.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + 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().(*MsgUpdateParams) + 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 x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + 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().(*MsgUpdateParams) + 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: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: 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 Authority", 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.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + 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 + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + 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, + } +} + +var ( + md_MsgUpdateParamsResponse protoreflect.MessageDescriptor +) + +func init() { + file_cosmos_auth_v1beta1_tx_proto_init() + md_MsgUpdateParamsResponse = File_cosmos_auth_v1beta1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) + +type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse + +func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(x) +} + +func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_auth_v1beta1_tx_proto_msgTypes[1] + 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_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} + +type fastReflection_MsgUpdateParamsResponse_messageType struct{} + +func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(nil) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// 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_MsgUpdateParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParamsResponse)(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_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// 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_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.auth.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.auth.v1beta1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.auth.v1beta1.MsgUpdateParamsResponse", 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = 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().(*MsgUpdateParamsResponse) + 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 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().(*MsgUpdateParamsResponse) + 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: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 +// protoc (unknown) +// source: cosmos/auth/v1beta1/tx.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/auth parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgUpdateParams) Reset() { + *x = MsgUpdateParams{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_auth_v1beta1_tx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParams) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return file_cosmos_auth_v1beta1_tx_proto_rawDescGZIP(), []int{0} +} + +func (x *MsgUpdateParams) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgUpdateParams) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgUpdateParamsResponse) Reset() { + *x = MsgUpdateParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_auth_v1beta1_tx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParamsResponse) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return file_cosmos_auth_v1beta1_tx_proto_rawDescGZIP(), []int{1} +} + +var File_cosmos_auth_v1beta1_tx_proto protoreflect.FileDescriptor + +var file_cosmos_auth_v1beta1_tx_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x67, 0x6f, 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, 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, 0x1a, 0x1e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x01, + 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x06, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x69, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x62, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x2c, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xc2, 0x01, 0x0a, 0x17, 0x63, + 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x30, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41, 0x58, 0xaa, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, + 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, + 0x75, 0x74, 0x68, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x3a, 0x3a, 0x41, 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_auth_v1beta1_tx_proto_rawDescOnce sync.Once + file_cosmos_auth_v1beta1_tx_proto_rawDescData = file_cosmos_auth_v1beta1_tx_proto_rawDesc +) + +func file_cosmos_auth_v1beta1_tx_proto_rawDescGZIP() []byte { + file_cosmos_auth_v1beta1_tx_proto_rawDescOnce.Do(func() { + file_cosmos_auth_v1beta1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_auth_v1beta1_tx_proto_rawDescData) + }) + return file_cosmos_auth_v1beta1_tx_proto_rawDescData +} + +var file_cosmos_auth_v1beta1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_auth_v1beta1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: cosmos.auth.v1beta1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: cosmos.auth.v1beta1.MsgUpdateParamsResponse + (*Params)(nil), // 2: cosmos.auth.v1beta1.Params +} +var file_cosmos_auth_v1beta1_tx_proto_depIdxs = []int32{ + 2, // 0: cosmos.auth.v1beta1.MsgUpdateParams.params:type_name -> cosmos.auth.v1beta1.Params + 0, // 1: cosmos.auth.v1beta1.Msg.UpdateParams:input_type -> cosmos.auth.v1beta1.MsgUpdateParams + 1, // 2: cosmos.auth.v1beta1.Msg.UpdateParams:output_type -> cosmos.auth.v1beta1.MsgUpdateParamsResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_cosmos_auth_v1beta1_tx_proto_init() } +func file_cosmos_auth_v1beta1_tx_proto_init() { + if File_cosmos_auth_v1beta1_tx_proto != nil { + return + } + file_cosmos_auth_v1beta1_auth_proto_init() + if !protoimpl.UnsafeEnabled { + file_cosmos_auth_v1beta1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_auth_v1beta1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_cosmos_auth_v1beta1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cosmos_auth_v1beta1_tx_proto_goTypes, + DependencyIndexes: file_cosmos_auth_v1beta1_tx_proto_depIdxs, + MessageInfos: file_cosmos_auth_v1beta1_tx_proto_msgTypes, + }.Build() + File_cosmos_auth_v1beta1_tx_proto = out.File + file_cosmos_auth_v1beta1_tx_proto_rawDesc = nil + file_cosmos_auth_v1beta1_tx_proto_goTypes = nil + file_cosmos_auth_v1beta1_tx_proto_depIdxs = nil +} diff --git a/api/cosmos/auth/v1beta1/tx_grpc.pb.go b/api/cosmos/auth/v1beta1/tx_grpc.pb.go new file mode 100644 index 0000000000..61a59ec669 --- /dev/null +++ b/api/cosmos/auth/v1beta1/tx_grpc.pb.go @@ -0,0 +1,113 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: cosmos/auth/v1beta1/tx.proto + +package authv1beta1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MsgClient interface { + // UpdateParams defines a governance operation for updating the x/auth module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc.ClientConnInterface +} + +func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/cosmos.auth.v1beta1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +// All implementations must embed UnimplementedMsgServer +// for forward compatibility +type MsgServer interface { + // UpdateParams defines a governance operation for updating the x/auth module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + mustEmbedUnimplementedMsgServer() +} + +// UnimplementedMsgServer must be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} +func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} + +// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MsgServer will +// result in compilation errors. +type UnsafeMsgServer interface { + mustEmbedUnimplementedMsgServer() +} + +func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { + s.RegisterService(&Msg_ServiceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.auth.v1beta1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Msg_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.auth.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/auth/v1beta1/tx.proto", +} diff --git a/baseapp/block_gas_test.go b/baseapp/block_gas_test.go index 747bda83f2..6351f0f34d 100644 --- a/baseapp/block_gas_test.go +++ b/baseapp/block_gas_test.go @@ -124,7 +124,7 @@ func TestBaseApp_BlockGas(t *testing.T) { require.Equal(t, []byte("ok"), okValue) } // check block gas is always consumed - baseGas := uint64(70184) // baseGas is the gas consumed before tx msg + baseGas := uint64(52744) // baseGas is the gas consumed before tx msg expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas) if expGasConsumed > txtypes.MaxGasWanted { // capped by gasLimit diff --git a/contrib/rosetta/rosetta-ci/data.tar.gz b/contrib/rosetta/rosetta-ci/data.tar.gz index fb05ed31c08174c7b8dff30b281b7872232ebdf9..faad07fe5a93c5efc1df6b0191f08dd0d87e564f 100644 GIT binary patch literal 43328 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 PftAYdqJz4If%^Xdg6js- literal 43673 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 T_n-UE=YReWf;lG>0QLd^t7GmS diff --git a/proto/cosmos/auth/v1beta1/genesis.proto b/proto/cosmos/auth/v1beta1/genesis.proto index c88b94ee4e..48f068b872 100644 --- a/proto/cosmos/auth/v1beta1/genesis.proto +++ b/proto/cosmos/auth/v1beta1/genesis.proto @@ -9,7 +9,7 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; // GenesisState defines the auth module's genesis state. message GenesisState { - // params defines all the paramaters of the module. + // params defines all the parameters of the module. Params params = 1 [(gogoproto.nullable) = false]; // accounts are the accounts present at genesis. diff --git a/proto/cosmos/auth/v1beta1/tx.proto b/proto/cosmos/auth/v1beta1/tx.proto new file mode 100644 index 0000000000..8e3d114b73 --- /dev/null +++ b/proto/cosmos/auth/v1beta1/tx.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// Msg defines the x/auth Msg service. +service Msg { + // UpdateParams defines a governance operation for updating the x/auth module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + // authority is the address of the governance account. + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the x/auth parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +message MsgUpdateParamsResponse {} diff --git a/simapp/app.go b/simapp/app.go index 5c82472368..34432a1aac 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -269,7 +269,7 @@ func NewSimApp( // NOTE: this is not required apps that don't use the simulator for fuzz testing // transactions overrideModules := map[string]module.AppModuleSimulation{ - authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), + authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), } app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules) diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index a3bcc8779e..b1327914df 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -1116,14 +1116,16 @@ func (suite *AnteTestSuite) TestAnteHandlerReCheck() { } for _, tc := range testCases { // set testcase parameters - suite.accountKeeper.SetParams(suite.ctx, tc.params) + err := suite.accountKeeper.SetParams(suite.ctx, tc.params) + suite.Require().NoError(err) - _, err := suite.anteHandler(suite.ctx, tx, false) + _, err = suite.anteHandler(suite.ctx, tx, false) suite.Require().NotNil(err, "tx does not fail on recheck with updated params in test case: %s", tc.name) // reset parameters to default values - suite.accountKeeper.SetParams(suite.ctx, types.DefaultParams()) + err = suite.accountKeeper.SetParams(suite.ctx, types.DefaultParams()) + suite.Require().NoError(err) } // require that local mempool fee check is still run on recheck since validator may change minFee between check and recheck diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index 4f69c40a25..faec682282 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -319,7 +319,8 @@ func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs // Make block-height non-zero to include accNum in SignBytes suite.ctx = suite.ctx.WithBlockHeight(1) - suite.accountKeeper.SetParams(suite.ctx, params) + err := suite.accountKeeper.SetParams(suite.ctx, params) + suite.Require().NoError(err) msgs := make([]sdk.Msg, len(privs)) accNums := make([]uint64, len(privs)) diff --git a/x/auth/ante/testutil_test.go b/x/auth/ante/testutil_test.go index eb5683ea0c..5167dac536 100644 --- a/x/auth/ante/testutil_test.go +++ b/x/auth/ante/testutil_test.go @@ -73,7 +73,8 @@ func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { suite.Require().NoError(err) suite.ctx = app.BaseApp.NewContext(isCheckTx, tmproto.Header{}).WithBlockHeight(1) - suite.accountKeeper.SetParams(suite.ctx, authtypes.DefaultParams()) + err = suite.accountKeeper.SetParams(suite.ctx, authtypes.DefaultParams()) + suite.Require().NoError(err) // We're using TestMsg encoding in some tests, so register it here. legacyAmino.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) diff --git a/x/auth/exported/exported.go b/x/auth/exported/exported.go new file mode 100644 index 0000000000..000114e619 --- /dev/null +++ b/x/auth/exported/exported.go @@ -0,0 +1,18 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +type ( + ParamSet = paramtypes.ParamSet + + // Subspace defines an interface that implements the legacy x/params Subspace + // type. + // + // NOTE: This is used solely for migration of x/params managed parameters. + Subspace interface { + GetParamSet(ctx sdk.Context, ps ParamSet) + } +) diff --git a/x/auth/keeper/account.go b/x/auth/keeper/account.go index a18a5240dc..bfa03ea1e6 100644 --- a/x/auth/keeper/account.go +++ b/x/auth/keeper/account.go @@ -27,19 +27,19 @@ func (ak AccountKeeper) NewAccount(ctx sdk.Context, acc types.AccountI) types.Ac // HasAccount implements AccountKeeperI. func (ak AccountKeeper) HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool { - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) return store.Has(types.AddressStoreKey(addr)) } // HasAccountAddressByID checks account address exists by id. func (ak AccountKeeper) HasAccountAddressByID(ctx sdk.Context, id uint64) bool { - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) return store.Has(types.AccountNumberStoreKey(id)) } // GetAccount implements AccountKeeperI. func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI { - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) bz := store.Get(types.AddressStoreKey(addr)) if bz == nil { return nil @@ -50,7 +50,7 @@ func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.A // GetAccountAddressById returns account address by id. func (ak AccountKeeper) GetAccountAddressByID(ctx sdk.Context, id uint64) string { - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) bz := store.Get(types.AccountNumberStoreKey(id)) if bz == nil { return "" @@ -71,7 +71,7 @@ func (ak AccountKeeper) GetAllAccounts(ctx sdk.Context) (accounts []types.Accoun // SetAccount implements AccountKeeperI. func (ak AccountKeeper) SetAccount(ctx sdk.Context, acc types.AccountI) { addr := acc.GetAddress() - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) bz, err := ak.MarshalAccount(acc) if err != nil { @@ -86,7 +86,7 @@ func (ak AccountKeeper) SetAccount(ctx sdk.Context, acc types.AccountI) { // NOTE: this will cause supply invariant violation if called func (ak AccountKeeper) RemoveAccount(ctx sdk.Context, acc types.AccountI) { addr := acc.GetAddress() - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) store.Delete(types.AddressStoreKey(addr)) store.Delete(types.AccountNumberStoreKey(acc.GetAccountNumber())) } @@ -94,7 +94,7 @@ func (ak AccountKeeper) RemoveAccount(ctx sdk.Context, acc types.AccountI) { // IterateAccounts iterates over all the stored accounts and performs a callback function. // Stops iteration when callback returns true. func (ak AccountKeeper) IterateAccounts(ctx sdk.Context, cb func(account types.AccountI) (stop bool)) { - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.AddressStoreKeyPrefix) defer iterator.Close() diff --git a/x/auth/keeper/genesis.go b/x/auth/keeper/genesis.go index 50d36381fd..44c0af2d3b 100644 --- a/x/auth/keeper/genesis.go +++ b/x/auth/keeper/genesis.go @@ -10,7 +10,9 @@ import ( // CONTRACT: old coins from the FeeCollectionKeeper need to be transferred through // a genesis port script to the new fee collector account func (ak AccountKeeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { - ak.SetParams(ctx, data.Params) + if err := ak.SetParams(ctx, data.Params); err != nil { + panic(err) + } accounts, err := types.UnpackAccounts(data.Accounts) if err != nil { diff --git a/x/auth/keeper/grpc_query.go b/x/auth/keeper/grpc_query.go index 9d37a4ecc9..58ed7ef32f 100644 --- a/x/auth/keeper/grpc_query.go +++ b/x/auth/keeper/grpc_query.go @@ -43,7 +43,7 @@ func (ak AccountKeeper) Accounts(c context.Context, req *types.QueryAccountsRequ } ctx := sdk.UnwrapSDKContext(c) - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) accountsStore := prefix.NewStore(store, types.AddressStoreKeyPrefix) var accounts []*codectypes.Any diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index d4e4435e05..1ab380ef1d 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -13,7 +13,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) // AccountKeeperI is the interface contract that x/auth's keeper implements. @@ -55,14 +54,17 @@ type AccountKeeperI interface { // AccountKeeper encodes/decodes accounts using the go-amino (binary) // encoding/decoding library. type AccountKeeper struct { - key storetypes.StoreKey - cdc codec.BinaryCodec - paramSubspace paramtypes.Subspace - permAddrs map[string]types.PermissionsForAddress + storeKey storetypes.StoreKey + cdc codec.BinaryCodec + permAddrs map[string]types.PermissionsForAddress // The prototypical AccountI constructor. proto func() types.AccountI addressCdc address.Codec + + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string } var _ AccountKeeperI = &AccountKeeper{} @@ -74,13 +76,9 @@ var _ AccountKeeperI = &AccountKeeper{} // and don't have to fit into any predefined structure. This auth module does not use account permissions internally, though other modules // may use auth.Keeper to access the accounts permissions map. func NewAccountKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, paramstore paramtypes.Subspace, proto func() types.AccountI, - maccPerms map[string][]string, bech32Prefix string, + cdc codec.BinaryCodec, storeKey storetypes.StoreKey, proto func() types.AccountI, + maccPerms map[string][]string, bech32Prefix string, authority string, ) AccountKeeper { - // set KeyTable if it has not already been set - if !paramstore.HasKeyTable() { - paramstore = paramstore.WithKeyTable(types.ParamKeyTable()) - } permAddrs := make(map[string]types.PermissionsForAddress) for name, perms := range maccPerms { @@ -90,15 +88,20 @@ func NewAccountKeeper( bech32Codec := newBech32Codec(bech32Prefix) return AccountKeeper{ - key: key, - proto: proto, - cdc: cdc, - paramSubspace: paramstore, - permAddrs: permAddrs, - addressCdc: bech32Codec, + storeKey: storeKey, + proto: proto, + cdc: cdc, + permAddrs: permAddrs, + addressCdc: bech32Codec, + authority: authority, } } +// GetAuthority returns the x/mint module's authority. +func (ak AccountKeeper) GetAuthority() string { + return ak.authority +} + // Logger returns a module-specific logger. func (ak AccountKeeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) @@ -128,7 +131,7 @@ func (ak AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint6 // If the global account number is not set, it initializes it with value 0. func (ak AccountKeeper) GetNextAccountNumber(ctx sdk.Context) uint64 { var accNumber uint64 - store := ctx.KVStore(ak.key) + store := ctx.KVStore(ak.storeKey) bz := store.Get(types.GlobalAccountNumberKey) if bz == nil { diff --git a/x/auth/keeper/keeper_test.go b/x/auth/keeper/keeper_test.go index e0ff0509b2..8bf9ca3a45 100644 --- a/x/auth/keeper/keeper_test.go +++ b/x/auth/keeper/keeper_test.go @@ -38,6 +38,7 @@ type KeeperTestSuite struct { legacyAmino *codec.LegacyAmino interfaceRegistry codectypes.InterfaceRegistry accountKeeper keeper.AccountKeeper + msgServer types.MsgServer } func (suite *KeeperTestSuite) SetupTest() { @@ -52,6 +53,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.app = app suite.ctx = app.BaseApp.NewContext(true, tmproto.Header{}) + suite.msgServer = keeper.NewMsgServerImpl(suite.accountKeeper) queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.interfaceRegistry) types.RegisterQueryServer(queryHelper, suite.accountKeeper) @@ -129,7 +131,8 @@ func (suite *KeeperTestSuite) TestGetSetParams() { ctx := suite.ctx params := types.DefaultParams() - suite.accountKeeper.SetParams(ctx, params) + err := suite.accountKeeper.SetParams(ctx, params) + suite.Require().NoError(err) actualParams := suite.accountKeeper.GetParams(ctx) suite.Require().Equal(params, actualParams) diff --git a/x/auth/keeper/migrations.go b/x/auth/keeper/migrations.go index 768bc7c10c..5826a6bb16 100644 --- a/x/auth/keeper/migrations.go +++ b/x/auth/keeper/migrations.go @@ -6,20 +6,23 @@ import ( v043 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v043" v046 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v046" + "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/types" sdk "github.com/cosmos/cosmos-sdk/types" + v2 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v2" ) // Migrator is a struct for handling in-place store migrations. type Migrator struct { - keeper AccountKeeper - queryServer grpc.Server + keeper AccountKeeper + queryServer grpc.Server + legacySubspace exported.Subspace } // NewMigrator returns a new Migrator. -func NewMigrator(keeper AccountKeeper, queryServer grpc.Server) Migrator { - return Migrator{keeper: keeper, queryServer: queryServer} +func NewMigrator(keeper AccountKeeper, queryServer grpc.Server, ss exported.Subspace) Migrator { + return Migrator{keeper: keeper, queryServer: queryServer, legacySubspace: ss} } // Migrate1to2 migrates from version 1 to 2. @@ -47,7 +50,15 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { // Migrate2to3 migrates from consensus version 2 to version 3. Specifically, for each account // we index the account's ID to their address. func (m Migrator) Migrate2to3(ctx sdk.Context) error { - return v046.MigrateStore(ctx, m.keeper.key, m.keeper.cdc) + return v046.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} + +// Migrate3to4 migrates the x/auth module state from the consensus version 3 to +// version 4. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the x/auth +// module state. +func (m Migrator) Migrate3to4(ctx sdk.Context) error { + return v2.Migrate(ctx, ctx.KVStore(m.keeper.storeKey), m.legacySubspace, m.keeper.cdc) } // V45_SetAccount implements V45_SetAccount @@ -56,7 +67,7 @@ func (m Migrator) Migrate2to3(ctx sdk.Context) error { // NOTE: This is used for testing purposes only. func (m Migrator) V45_SetAccount(ctx sdk.Context, acc types.AccountI) error { addr := acc.GetAddress() - store := ctx.KVStore(m.keeper.key) + store := ctx.KVStore(m.keeper.storeKey) bz, err := m.keeper.MarshalAccount(acc) if err != nil { diff --git a/x/auth/keeper/msg_server.go b/x/auth/keeper/msg_server.go new file mode 100644 index 0000000000..b79d8cbacc --- /dev/null +++ b/x/auth/keeper/msg_server.go @@ -0,0 +1,36 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + AccountKeeper +} + +// NewMsgServerImpl returns an implementation of the x/auth MsgServer interface. +func NewMsgServerImpl(ak AccountKeeper) types.MsgServer { + return &msgServer{ + AccountKeeper: ak, + } +} + +func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if ms.authority != req.Authority { + return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", ms.authority, req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := ms.SetParams(ctx, req.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/auth/keeper/msg_server_test.go b/x/auth/keeper/msg_server_test.go new file mode 100644 index 0000000000..03b923d450 --- /dev/null +++ b/x/auth/keeper/msg_server_test.go @@ -0,0 +1,111 @@ +package keeper_test + +import ( + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (s *KeeperTestSuite) TestUpdateParams() { + testCases := []struct { + name string + req *types.MsgUpdateParams + expectErr bool + expErrMsg string + }{ + { + name: "set invalid authority", + req: &types.MsgUpdateParams{ + Authority: "foo", + }, + expectErr: true, + expErrMsg: "invalid authority", + }, + { + name: "set invalid max memo characters", + req: &types.MsgUpdateParams{ + Authority: s.accountKeeper.GetAuthority(), + Params: types.Params{ + MaxMemoCharacters: 0, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + }, + expectErr: true, + expErrMsg: "invalid max memo characters", + }, + { + name: "set invalid tx sig limit", + req: &types.MsgUpdateParams{ + Authority: s.accountKeeper.GetAuthority(), + Params: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 0, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + }, + expectErr: true, + expErrMsg: "invalid tx signature limit", + }, + { + name: "set invalid tx size cost per bytes", + req: &types.MsgUpdateParams{ + Authority: s.accountKeeper.GetAuthority(), + Params: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 0, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + }, + expectErr: true, + expErrMsg: "invalid tx size cost per byte", + }, + { + name: "set invalid sig verify cost ED25519", + req: &types.MsgUpdateParams{ + Authority: s.accountKeeper.GetAuthority(), + Params: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 0, + SigVerifyCostSecp256k1: 511, + }, + }, + expectErr: true, + expErrMsg: "invalid ED25519 signature verification cost", + }, + { + name: "set invalid sig verify cost Secp256k1", + req: &types.MsgUpdateParams{ + Authority: s.accountKeeper.GetAuthority(), + Params: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 0, + }, + }, + expectErr: true, + expErrMsg: "invalid SECK256k1 signature verification cost", + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + _, err := s.msgServer.UpdateParams(s.ctx, tc.req) + if tc.expectErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expErrMsg) + } else { + s.Require().NoError(err) + } + }) + } +} diff --git a/x/auth/keeper/params.go b/x/auth/keeper/params.go index 0236c7ae16..680f7c1583 100644 --- a/x/auth/keeper/params.go +++ b/x/auth/keeper/params.go @@ -6,12 +6,25 @@ import ( ) // SetParams sets the auth module's parameters. -func (ak AccountKeeper) SetParams(ctx sdk.Context, params types.Params) { - ak.paramSubspace.SetParamSet(ctx, ¶ms) +func (ak AccountKeeper) SetParams(ctx sdk.Context, params types.Params) error { + if err := params.Validate(); err != nil { + return err + } + + store := ctx.KVStore(ak.storeKey) + bz := ak.cdc.MustMarshal(¶ms) + store.Set(types.ParamsKey, bz) + + return nil } // GetParams gets the auth module's parameters. func (ak AccountKeeper) GetParams(ctx sdk.Context) (params types.Params) { - ak.paramSubspace.GetParamSet(ctx, ¶ms) - return + store := ctx.KVStore(ak.storeKey) + bz := store.Get(types.ParamsKey) + if bz == nil { + return params + } + ak.cdc.MustUnmarshal(bz, ¶ms) + return params } diff --git a/x/auth/keeper/params_test.go b/x/auth/keeper/params_test.go new file mode 100644 index 0000000000..4853fe5634 --- /dev/null +++ b/x/auth/keeper/params_test.go @@ -0,0 +1,92 @@ +package keeper_test + +import ( + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (s *KeeperTestSuite) TestParams() { + testCases := []struct { + name string + input types.Params + expectErr bool + expErrMsg string + }{ + { + name: "set invalid max memo characters", + input: types.Params{ + MaxMemoCharacters: 0, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + expectErr: true, + expErrMsg: "invalid max memo characters", + }, + { + name: "set invalid tx sig limit", + input: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 0, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + expectErr: true, + expErrMsg: "invalid tx signature limit", + }, + { + name: "set invalid tx size cost per bytes", + input: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 0, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 511, + }, + expectErr: true, + expErrMsg: "invalid tx size cost per byte", + }, + { + name: "set invalid sig verify cost ED25519", + input: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 0, + SigVerifyCostSecp256k1: 511, + }, + expectErr: true, + expErrMsg: "invalid ED25519 signature verification cost", + }, + { + name: "set invalid sig verify cost Secp256k1", + input: types.Params{ + MaxMemoCharacters: 140, + TxSigLimit: 9, + TxSizeCostPerByte: 5, + SigVerifyCostED25519: 694, + SigVerifyCostSecp256k1: 0, + }, + expectErr: true, + expErrMsg: "invalid SECK256k1 signature verification cost", + }, + } + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + expected := s.accountKeeper.GetParams(s.ctx) + err := s.accountKeeper.SetParams(s.ctx, tc.input) + if tc.expectErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expErrMsg) + } else { + expected = tc.input + s.Require().NoError(err) + } + + params := s.accountKeeper.GetParams(s.ctx) + s.Require().Equal(expected, params) + }) + } +} diff --git a/x/auth/migrations/v043/store_test.go b/x/auth/migrations/v043/store_test.go index afd2b9a67d..afb89bbe29 100644 --- a/x/auth/migrations/v043/store_test.go +++ b/x/auth/migrations/v043/store_test.go @@ -10,10 +10,15 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/cosmos/cosmos-sdk/testutil" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/testutil" + v2 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v2" + authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" @@ -22,21 +27,44 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) +type mockSubspace struct { + ps authtypes.Params +} + +func newMockSubspace(ps authtypes.Params) mockSubspace { + return mockSubspace{ps: ps} +} + +func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps authexported.ParamSet) { + *ps.(*authtypes.Params) = ms.ps +} + func TestMigrateVestingAccounts(t *testing.T) { + encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + cdc := encCfg.Codec + + storeKey := sdk.NewKVStoreKey(v2.ModuleName) + tKey := sdk.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + store := ctx.KVStore(storeKey) + var ( accountKeeper keeper.AccountKeeper bankKeeper bankkeeper.Keeper stakingKeeper *stakingkeeper.Keeper ) app, err := simtestutil.Setup( - testutil.AppConfig, + authtestutil.AppConfig, &accountKeeper, &bankKeeper, &stakingKeeper, ) require.NoError(t, err) - ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + legacySubspace := newMockSubspace(authtypes.DefaultParams()) + require.NoError(t, v2.Migrate(ctx, store, legacySubspace, cdc)) + + ctx = app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) stakingKeeper.SetParams(ctx, stakingtypes.DefaultParams()) testCases := []struct { @@ -58,7 +86,9 @@ func TestMigrateVestingAccounts(t *testing.T) { ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) - accountKeeper.SetParams(ctx, authtypes.DefaultParams()) + err := accountKeeper.SetParams(ctx, authtypes.DefaultParams()) + require.NoError(t, err) + accountKeeper.SetAccount(ctx, delayedAccount) _, err = stakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) @@ -562,7 +592,9 @@ func TestMigrateVestingAccounts(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { - accountKeeper.SetParams(ctx, authtypes.DefaultParams()) + err := accountKeeper.SetParams(ctx, authtypes.DefaultParams()) + require.NoError(t, err) + addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 1, sdk.NewInt(tc.tokenAmount)) delegatorAddr := addrs[0] @@ -582,7 +614,7 @@ func TestMigrateVestingAccounts(t *testing.T) { require.True(t, ok) require.NoError(t, tc.garbageFunc(ctx, vestingAccount, accountKeeper)) - m := keeper.NewMigrator(accountKeeper, app.GRPCQueryRouter()) + m := keeper.NewMigrator(accountKeeper, app.GRPCQueryRouter(), legacySubspace) require.NoError(t, m.Migrate1to2(ctx)) var expVested sdk.Coins diff --git a/x/auth/migrations/v046/store_test.go b/x/auth/migrations/v046/store_test.go index 13db36689a..e063fac556 100644 --- a/x/auth/migrations/v046/store_test.go +++ b/x/auth/migrations/v046/store_test.go @@ -6,36 +6,65 @@ import ( "time" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/testutil" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/testutil" + v2 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v2" + authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/auth/types" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) +type mockSubspace struct { + ps authtypes.Params +} + +func newMockSubspace(ps authtypes.Params) mockSubspace { + return mockSubspace{ps: ps} +} + +func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps authexported.ParamSet) { + *ps.(*authtypes.Params) = ms.ps +} + // TestMigrateMapAccAddressToAccNumberKey test cases for state migration of map to accAddr to accNum func TestMigrateMapAccAddressToAccNumberKey(t *testing.T) { + encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + cdc := encCfg.Codec + + storeKey := sdk.NewKVStoreKey(v2.ModuleName) + tKey := sdk.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + store := ctx.KVStore(storeKey) + var ( accountKeeper keeper.AccountKeeper ) app, err := simtestutil.Setup( - testutil.AppConfig, + authtestutil.AppConfig, &accountKeeper, ) require.NoError(t, err) + legacySubspace := newMockSubspace(authtypes.DefaultParams()) + require.NoError(t, v2.Migrate(ctx, store, legacySubspace, cdc)) + // new base account senderPrivKey := secp256k1.GenPrivKey() randAccNumber := uint64(rand.Intn(100000-10000) + 10000) - acc := types.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), randAccNumber, 0) + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), randAccNumber, 0) - ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) // migrator - m := keeper.NewMigrator(accountKeeper, app.GRPCQueryRouter()) + m := keeper.NewMigrator(accountKeeper, app.GRPCQueryRouter(), legacySubspace) // set the account to store with map acc addr to acc number require.NoError(t, m.V45_SetAccount(ctx, acc)) diff --git a/x/auth/migrations/v2/migrate.go b/x/auth/migrations/v2/migrate.go new file mode 100644 index 0000000000..7c5a2b2f38 --- /dev/null +++ b/x/auth/migrations/v2/migrate.go @@ -0,0 +1,35 @@ +package v2 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +const ( + ModuleName = "auth" +) + +var ( + ParamsKey = []byte{0x01} +) + +// Migrate migrates the x/auth module state from the consensus version 3 to +// version 4. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the x/auth +// module state. +func Migrate(ctx sdk.Context, store sdk.KVStore, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error { + var currParams types.Params + legacySubspace.GetParamSet(ctx, &currParams) + + if err := currParams.Validate(); err != nil { + return err + } + + bz := cdc.MustMarshal(&currParams) + store.Set(ParamsKey, bz) + + return nil + +} diff --git a/x/auth/migrations/v2/migrator_test.go b/x/auth/migrations/v2/migrator_test.go new file mode 100644 index 0000000000..76a5389e7e --- /dev/null +++ b/x/auth/migrations/v2/migrator_test.go @@ -0,0 +1,46 @@ +package v2_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/exported" + v2 "github.com/cosmos/cosmos-sdk/x/auth/migrations/v2" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +type mockSubspace struct { + ps types.Params +} + +func newMockSubspace(ps types.Params) mockSubspace { + return mockSubspace{ps: ps} +} + +func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) { + *ps.(*types.Params) = ms.ps +} + +func TestMigrate(t *testing.T) { + encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}) + cdc := encCfg.Codec + + storeKey := sdk.NewKVStoreKey(v2.ModuleName) + tKey := sdk.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + store := ctx.KVStore(storeKey) + + legacySubspace := newMockSubspace(types.DefaultParams()) + require.NoError(t, v2.Migrate(ctx, store, legacySubspace, cdc)) + + var res types.Params + bz := store.Get(v2.ParamsKey) + require.NoError(t, cdc.Unmarshal(bz, &res)) + require.Equal(t, legacySubspace.ps, res) +} diff --git a/x/auth/module.go b/x/auth/module.go index 8b1885aa67..c72e76848e 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -17,7 +17,6 @@ import ( "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/runtime" store "github.com/cosmos/cosmos-sdk/store/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -26,11 +25,16 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/simulation" "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) +// ConsensusVersion defines the current x/auth module consensus version. +const ConsensusVersion = 4 + var ( _ module.AppModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} @@ -94,14 +98,18 @@ type AppModule struct { accountKeeper keeper.AccountKeeper randGenAccountsFn types.RandomGenesisAccountsFn + + // legacySubspace is used solely for migration of x/params managed parameters + legacySubspace exported.Subspace } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, accountKeeper keeper.AccountKeeper, randGenAccountsFn types.RandomGenesisAccountsFn) AppModule { +func NewAppModule(cdc codec.Codec, accountKeeper keeper.AccountKeeper, randGenAccountsFn types.RandomGenesisAccountsFn, ss exported.Subspace) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, accountKeeper: accountKeeper, randGenAccountsFn: randGenAccountsFn, + legacySubspace: ss, } } @@ -131,17 +139,20 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.accountKeeper)) types.RegisterQueryServer(cfg.QueryServer(), am.accountKeeper) - m := keeper.NewMigrator(am.accountKeeper, cfg.QueryServer()) - err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) - if err != nil { + m := keeper.NewMigrator(am.accountKeeper, cfg.QueryServer(), am.legacySubspace) + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { panic(err) } - err = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3) - if err != nil { + if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil { panic(err) } + + if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil { + panic(fmt.Sprintf("failed to migrate x/%s from version 3 to 4: %v", types.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the auth module. It returns @@ -161,7 +172,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 3 } +func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion } // BeginBlock returns the begin blocker for the auth module. func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} @@ -186,7 +197,7 @@ func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.We // RandomizedParams creates randomized auth param changes for the simulator. func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return simulation.ParamChanges(r) + return []simtypes.ParamChange{} } // RegisterStoreDecoder registers a decoder for auth module's types @@ -216,10 +227,12 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper { type authInputs struct { depinject.In - Config *modulev1.Module - Key *store.KVStoreKey - Cdc codec.Codec - Subspace paramtypes.Subspace + Config *modulev1.Module + Key *store.KVStoreKey + Cdc codec.Codec + + // LegacySubspace is used solely for migration of x/params managed parameters + LegacySubspace exported.Subspace } type authOutputs struct { @@ -235,8 +248,8 @@ func provideModule(in authInputs) authOutputs { maccPerms[permission.Account] = permission.Permissions } - k := keeper.NewAccountKeeper(in.Cdc, in.Key, in.Subspace, types.ProtoBaseAccount, maccPerms, in.Config.Bech32Prefix) - m := NewAppModule(in.Cdc, k, simulation.RandomGenesisAccounts) + k := keeper.NewAccountKeeper(in.Cdc, in.Key, types.ProtoBaseAccount, maccPerms, in.Config.Bech32Prefix, types.NewModuleAddress(govtypes.ModuleName).String()) + m := NewAppModule(in.Cdc, k, simulation.RandomGenesisAccounts, in.LegacySubspace) return authOutputs{AccountKeeper: k, Module: runtime.WrapAppModule(m)} } diff --git a/x/auth/types/codec.go b/x/auth/types/codec.go index 29561dfe01..020fa7c0d9 100644 --- a/x/auth/types/codec.go +++ b/x/auth/types/codec.go @@ -2,6 +2,7 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,6 +18,9 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterInterface((*AccountI)(nil), nil) cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil) + cdc.RegisterConcrete(Params{}, "cosmos-sdk/x/auth/Params", nil) + + legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "cosmos-sdk/x/auth/MsgUpdateParams") legacytx.RegisterLegacyAminoCodec(cdc) } @@ -37,6 +41,10 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &BaseAccount{}, &ModuleAccount{}, ) + + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgUpdateParams{}, + ) } var ( diff --git a/x/auth/types/genesis.pb.go b/x/auth/types/genesis.pb.go index 4e7396ab7c..aadea95e72 100644 --- a/x/auth/types/genesis.pb.go +++ b/x/auth/types/genesis.pb.go @@ -26,7 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the auth module's genesis state. type GenesisState struct { - // params defines all the paramaters of the module. + // params defines all the parameters of the module. Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` // accounts are the accounts present at genesis. Accounts []*types.Any `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts,omitempty"` diff --git a/x/auth/types/keys.go b/x/auth/types/keys.go index e3488bbc07..0a3582ca29 100644 --- a/x/auth/types/keys.go +++ b/x/auth/types/keys.go @@ -19,6 +19,9 @@ const ( ) var ( + // ParamsKey is the prefix for params key + ParamsKey = []byte{0x00} + // AddressStoreKeyPrefix prefix for account-by-address store AddressStoreKeyPrefix = []byte{0x01} diff --git a/x/auth/types/msgs.go b/x/auth/types/msgs.go new file mode 100644 index 0000000000..c0f25ee1e0 --- /dev/null +++ b/x/auth/types/msgs.go @@ -0,0 +1,32 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var _ sdk.Msg = &MsgUpdateParams{} + +// GetSignBytes implements the LegacyMsg interface. +func (msg MsgUpdateParams) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (msg *MsgUpdateParams) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Authority) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (msg *MsgUpdateParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + return sdkerrors.Wrap(err, "invalid authority address") + } + + if err := msg.Params.Validate(); err != nil { + return err + } + + return nil +} diff --git a/x/auth/types/params.go b/x/auth/types/params.go index 5374534417..a97544e6e6 100644 --- a/x/auth/types/params.go +++ b/x/auth/types/params.go @@ -4,8 +4,6 @@ import ( "fmt" "sigs.k8s.io/yaml" - - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) // Default parameter values @@ -17,17 +15,6 @@ const ( DefaultSigVerifyCostSecp256k1 uint64 = 1000 ) -// Parameter keys -var ( - KeyMaxMemoCharacters = []byte("MaxMemoCharacters") - KeyTxSigLimit = []byte("TxSigLimit") - KeyTxSizeCostPerByte = []byte("TxSizeCostPerByte") - KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519") - KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1") -) - -var _ paramtypes.ParamSet = &Params{} - // NewParams creates a new Params object func NewParams( maxMemoCharacters, txSigLimit, txSizeCostPerByte, sigVerifyCostED25519, sigVerifyCostSecp256k1 uint64, @@ -41,23 +28,6 @@ func NewParams( } } -// ParamKeyTable for auth module -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -// ParamSetPairs implements the ParamSet interface and returns all the key/value pairs -// pairs of auth module's parameters. -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyMaxMemoCharacters, &p.MaxMemoCharacters, validateMaxMemoCharacters), - paramtypes.NewParamSetPair(KeyTxSigLimit, &p.TxSigLimit, validateTxSigLimit), - paramtypes.NewParamSetPair(KeyTxSizeCostPerByte, &p.TxSizeCostPerByte, validateTxSizeCostPerByte), - paramtypes.NewParamSetPair(KeySigVerifyCostED25519, &p.SigVerifyCostED25519, validateSigVerifyCostED25519), - paramtypes.NewParamSetPair(KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1, validateSigVerifyCostSecp256k1), - } -} - // DefaultParams returns a default set of parameters. func DefaultParams() Params { return Params{ diff --git a/x/auth/types/params_legacy.go b/x/auth/types/params_legacy.go new file mode 100644 index 0000000000..6131c56d11 --- /dev/null +++ b/x/auth/types/params_legacy.go @@ -0,0 +1,40 @@ +/* +NOTE: Usage of x/params to manage parameters is deprecated in favor of x/gov +controlled execution of MsgUpdateParams messages. These types remains solely +for migration purposes and will be removed in a future release. +*/ +package types + +import ( + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter keys +var ( + KeyMaxMemoCharacters = []byte("MaxMemoCharacters") + KeyTxSigLimit = []byte("TxSigLimit") + KeyTxSizeCostPerByte = []byte("TxSizeCostPerByte") + KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519") + KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1") +) + +var _ paramtypes.ParamSet = &Params{} + +// ParamKeyTable for auth module +// +// NOTE: Deprecated. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// ParamSetPairs implements the ParamSet interface and returns all the key/value pairs +// pairs of auth module's parameters. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyMaxMemoCharacters, &p.MaxMemoCharacters, validateMaxMemoCharacters), + paramtypes.NewParamSetPair(KeyTxSigLimit, &p.TxSigLimit, validateTxSigLimit), + paramtypes.NewParamSetPair(KeyTxSizeCostPerByte, &p.TxSizeCostPerByte, validateTxSizeCostPerByte), + paramtypes.NewParamSetPair(KeySigVerifyCostED25519, &p.SigVerifyCostED25519, validateSigVerifyCostED25519), + paramtypes.NewParamSetPair(KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1, validateSigVerifyCostSecp256k1), + } +} diff --git a/x/auth/types/tx.pb.go b/x/auth/types/tx.pb.go new file mode 100644 index 0000000000..9b60a3c289 --- /dev/null +++ b/x/auth/types/tx.pb.go @@ -0,0 +1,603 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/auth/v1beta1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/auth parameters to update. + // + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_c2d62bd9c4c212e5, []int{0} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c2d62bd9c4c212e5, []int{1} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgUpdateParams)(nil), "cosmos.auth.v1beta1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.auth.v1beta1.MsgUpdateParamsResponse") +} + +func init() { proto.RegisterFile("cosmos/auth/v1beta1/tx.proto", fileDescriptor_c2d62bd9c4c212e5) } + +var fileDescriptor_c2d62bd9c4c212e5 = []byte{ + // 310 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0x2c, 0x2d, 0xc9, 0xd0, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, + 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xc8, 0xea, 0x81, 0x64, 0xf5, + 0xa0, 0xb2, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0x79, 0x7d, 0x10, 0x0b, 0xa2, 0x54, 0x4a, + 0x12, 0xa2, 0x34, 0x1e, 0x22, 0x01, 0xd5, 0x07, 0x91, 0x12, 0x87, 0xda, 0x91, 0x5b, 0x9c, 0xae, + 0x5f, 0x66, 0x08, 0xa2, 0xa0, 0x12, 0x72, 0xd8, 0x2c, 0x07, 0xdb, 0x05, 0x96, 0x57, 0x9a, 0xc2, + 0xc8, 0xc5, 0xef, 0x5b, 0x9c, 0x1e, 0x5a, 0x90, 0x92, 0x58, 0x92, 0x1a, 0x90, 0x58, 0x94, 0x98, + 0x5b, 0x2c, 0x64, 0xc6, 0xc5, 0x09, 0x52, 0x91, 0x5f, 0x94, 0x59, 0x52, 0x29, 0xc1, 0xa8, 0xc0, + 0xa8, 0xc1, 0xe9, 0x24, 0x71, 0x69, 0x8b, 0xae, 0x08, 0xd4, 0x46, 0xc7, 0x94, 0x94, 0xa2, 0xd4, + 0xe2, 0xe2, 0xe0, 0x92, 0xa2, 0xcc, 0xbc, 0xf4, 0x20, 0x84, 0x52, 0x21, 0x4b, 0x2e, 0xb6, 0x02, + 0xb0, 0x09, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0xd2, 0x7a, 0x58, 0xfc, 0xa6, 0x07, 0xb1, + 0xc4, 0x89, 0xe5, 0xc4, 0x3d, 0x79, 0x86, 0x20, 0xa8, 0x06, 0x2b, 0xbe, 0xa6, 0xe7, 0x1b, 0xb4, + 0x10, 0x46, 0x29, 0x49, 0x72, 0x89, 0xa3, 0xb9, 0x2a, 0x28, 0xb5, 0xb8, 0x20, 0x3f, 0xaf, 0x38, + 0xd5, 0x28, 0x93, 0x8b, 0xd9, 0xb7, 0x38, 0x5d, 0x28, 0x89, 0x8b, 0x07, 0xc5, 0xd1, 0x2a, 0x58, + 0x2d, 0x43, 0x33, 0x44, 0x4a, 0x87, 0x18, 0x55, 0x30, 0xab, 0x9c, 0x9c, 0x4f, 0x3c, 0x92, 0x63, + 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, + 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x33, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, + 0x3f, 0x17, 0x1a, 0x11, 0x50, 0x4a, 0xb7, 0x38, 0x25, 0x5b, 0xbf, 0x02, 0x12, 0xdc, 0x25, 0x95, + 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x80, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x46, 0x68, + 0x6d, 0x75, 0x07, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // UpdateParams defines a governance operation for updating the x/auth module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/cosmos.auth.v1beta1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // UpdateParams defines a governance operation for updating the x/auth module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.auth.v1beta1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.auth.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/auth/v1beta1/tx.proto", +} + +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return 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 fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return 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 fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index 0c6caee701..1c4390abbc 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank/keeper" "github.com/cosmos/cosmos-sdk/x/bank/testutil" "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" ) @@ -86,8 +87,8 @@ func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[str maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} maccPerms[randomPerm] = []string{"random"} authKeeper := authkeeper.NewAccountKeeper( - appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), - authtypes.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix, + appCodec, app.GetKey(types.StoreKey), authtypes.ProtoBaseAccount, + maccPerms, sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) keeper := keeper.NewBaseKeeper( appCodec, app.GetKey(types.StoreKey), authKeeper, @@ -279,7 +280,7 @@ func (suite *IntegrationTestSuite) TestSupply_BurnCoins() { Require(). NoError(keeper.MintCoins(ctx, authtypes.Minter, initCoins)) supplyAfterInflation, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) - + suite.Require().NoError(err) suite.Require().Panics(func() { keeper.BurnCoins(ctx, "", initCoins) }, "no module account") // nolint:errcheck suite.Require().Panics(func() { keeper.BurnCoins(ctx, authtypes.Minter, initCoins) }, "invalid permission") // nolint:errcheck suite.Require().Panics(func() { keeper.BurnCoins(ctx, randomPerm, supplyAfterInflation) }, "random permission") // nolint:errcheck @@ -304,8 +305,8 @@ func (suite *IntegrationTestSuite) TestSupply_BurnCoins() { authKeeper.SetModuleAccount(ctx, multiPermAcc) err = keeper.BurnCoins(ctx, multiPermAcc.GetName(), initCoins) - supplyAfterBurn, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) suite.Require().NoError(err) + supplyAfterBurn, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) suite.Require().NoError(err) suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, multiPermAcc.GetName()).String()) suite.Require().Equal(supplyAfterInflation.Sub(initCoins...), supplyAfterBurn) @@ -1053,8 +1054,9 @@ func (suite *IntegrationTestSuite) TestBalanceTrackingEvents() { maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} suite.app.AccountKeeper = authkeeper.NewAccountKeeper( - suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), suite.app.GetSubspace(authtypes.ModuleName), + suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), authtypes.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) suite.app.BankKeeper = keeper.NewBaseKeeper(suite.app.AppCodec(), suite.app.GetKey(types.StoreKey), @@ -1180,8 +1182,9 @@ func (suite *IntegrationTestSuite) TestMintCoinRestrictions() { maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} suite.app.AccountKeeper = authkeeper.NewAccountKeeper( - suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), suite.app.GetSubspace(authtypes.ModuleName), + suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), authtypes.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) suite.app.AccountKeeper.SetModuleAccount(suite.ctx, multiPermAcc)