From 555779be2a44aca19825bdcdeb309c848473d7b4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:15:54 +0100 Subject: [PATCH 01/21] init commit --- api/cosmos/mint/v1beta1/genesis.pulsar.go | 8 +- api/cosmos/mint/v1beta1/mint.pulsar.go | 2 +- api/cosmos/mint/v1beta1/tx.pulsar.go | 1091 +++++++++++++++++++++ api/cosmos/mint/v1beta1/tx_grpc.pb.go | 113 +++ proto/cosmos/mint/v1beta1/genesis.proto | 8 +- proto/cosmos/mint/v1beta1/mint.proto | 2 +- proto/cosmos/mint/v1beta1/tx.proto | 39 + x/mint/types/genesis.pb.go | 8 +- x/mint/types/mint.pb.go | 2 +- x/mint/types/tx.pb.go | 603 ++++++++++++ 10 files changed, 1870 insertions(+), 6 deletions(-) create mode 100644 api/cosmos/mint/v1beta1/tx.pulsar.go create mode 100644 api/cosmos/mint/v1beta1/tx_grpc.pb.go create mode 100644 proto/cosmos/mint/v1beta1/tx.proto create mode 100644 x/mint/types/tx.pb.go diff --git a/api/cosmos/mint/v1beta1/genesis.pulsar.go b/api/cosmos/mint/v1beta1/genesis.pulsar.go index 51e6ad46aab..22e05176567 100644 --- a/api/cosmos/mint/v1beta1/genesis.pulsar.go +++ b/api/cosmos/mint/v1beta1/genesis.pulsar.go @@ -548,7 +548,13 @@ type GenesisState struct { // minter is a space for holding current inflation information. Minter *Minter `protobuf:"bytes,1,opt,name=minter,proto3" json:"minter,omitempty"` - // params defines all the paramaters of the module. + // params defines all the parameters of the module. + // + // Deprecated: Use governance to submit a MsgUpdateParams message to instruct + // the x/mint module to update the relevant parameters. + // + // Since the cosmos-sdk 0.47 version, this only exists for backwards + // compatibility of genesis state. Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` } diff --git a/api/cosmos/mint/v1beta1/mint.pulsar.go b/api/cosmos/mint/v1beta1/mint.pulsar.go index a7a67703c5d..a9798476db8 100644 --- a/api/cosmos/mint/v1beta1/mint.pulsar.go +++ b/api/cosmos/mint/v1beta1/mint.pulsar.go @@ -1281,7 +1281,7 @@ func (x *Minter) GetAnnualProvisions() string { return "" } -// Params holds parameters for the mint module. +// Params defines the parameters for the x/mint module. type Params struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/api/cosmos/mint/v1beta1/tx.pulsar.go b/api/cosmos/mint/v1beta1/tx.pulsar.go new file mode 100644 index 00000000000..28b6f60b859 --- /dev/null +++ b/api/cosmos/mint/v1beta1/tx.pulsar.go @@ -0,0 +1,1091 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package mintv1beta1 + +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_mint_v1beta1_tx_proto_init() + md_MsgUpdateParams = File_cosmos_mint_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_mint_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.mint.v1beta1.MsgUpdateParams.authority": + return x.Authority != "" + case "cosmos.mint.v1beta1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParams.authority": + x.Authority = "" + case "cosmos.mint.v1beta1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "cosmos.mint.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.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "cosmos.mint.v1beta1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "cosmos.mint.v1beta1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message cosmos.mint.v1beta1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "cosmos.mint.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.mint.v1beta1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.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_mint_v1beta1_tx_proto_init() + md_MsgUpdateParamsResponse = File_cosmos_mint_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_mint_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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.v1beta1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.mint.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.mint.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/mint/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) +) + +// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade 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/mint 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_mint_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_mint_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_mint_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_mint_v1beta1_tx_proto_rawDescGZIP(), []int{1} +} + +var File_cosmos_mint_v1beta1_tx_proto protoreflect.FileDescriptor + +var file_cosmos_mint_v1beta1_tx_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 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, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 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, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 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, 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, 0x6d, 0x69, 0x6e, 0x74, 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, + 0x6d, 0x69, 0x6e, 0x74, 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, 0x6d, 0x69, 0x6e, 0x74, 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, 0x6d, 0x69, 0x6e, 0x74, 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, 0x6d, 0x69, 0x6e, 0x74, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x69, 0x6e, 0x74, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x4d, 0x58, 0xaa, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x4d, 0x69, 0x6e, 0x74, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, + 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x4d, 0x69, 0x6e, 0x74, 0x5c, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1f, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x4d, + 0x69, 0x6e, 0x74, 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, 0x4d, 0x69, 0x6e, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_mint_v1beta1_tx_proto_rawDescOnce sync.Once + file_cosmos_mint_v1beta1_tx_proto_rawDescData = file_cosmos_mint_v1beta1_tx_proto_rawDesc +) + +func file_cosmos_mint_v1beta1_tx_proto_rawDescGZIP() []byte { + file_cosmos_mint_v1beta1_tx_proto_rawDescOnce.Do(func() { + file_cosmos_mint_v1beta1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_mint_v1beta1_tx_proto_rawDescData) + }) + return file_cosmos_mint_v1beta1_tx_proto_rawDescData +} + +var file_cosmos_mint_v1beta1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_mint_v1beta1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: cosmos.mint.v1beta1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: cosmos.mint.v1beta1.MsgUpdateParamsResponse + (*Params)(nil), // 2: cosmos.mint.v1beta1.Params +} +var file_cosmos_mint_v1beta1_tx_proto_depIdxs = []int32{ + 2, // 0: cosmos.mint.v1beta1.MsgUpdateParams.params:type_name -> cosmos.mint.v1beta1.Params + 0, // 1: cosmos.mint.v1beta1.Msg.UpdateParams:input_type -> cosmos.mint.v1beta1.MsgUpdateParams + 1, // 2: cosmos.mint.v1beta1.Msg.UpdateParams:output_type -> cosmos.mint.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_mint_v1beta1_tx_proto_init() } +func file_cosmos_mint_v1beta1_tx_proto_init() { + if File_cosmos_mint_v1beta1_tx_proto != nil { + return + } + file_cosmos_mint_v1beta1_mint_proto_init() + if !protoimpl.UnsafeEnabled { + file_cosmos_mint_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_mint_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_mint_v1beta1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cosmos_mint_v1beta1_tx_proto_goTypes, + DependencyIndexes: file_cosmos_mint_v1beta1_tx_proto_depIdxs, + MessageInfos: file_cosmos_mint_v1beta1_tx_proto_msgTypes, + }.Build() + File_cosmos_mint_v1beta1_tx_proto = out.File + file_cosmos_mint_v1beta1_tx_proto_rawDesc = nil + file_cosmos_mint_v1beta1_tx_proto_goTypes = nil + file_cosmos_mint_v1beta1_tx_proto_depIdxs = nil +} diff --git a/api/cosmos/mint/v1beta1/tx_grpc.pb.go b/api/cosmos/mint/v1beta1/tx_grpc.pb.go new file mode 100644 index 00000000000..4e5c2528b28 --- /dev/null +++ b/api/cosmos/mint/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/mint/v1beta1/tx.proto + +package mintv1beta1 + +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/mint 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.mint.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/mint 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.mint.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.mint.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/mint/v1beta1/tx.proto", +} diff --git a/proto/cosmos/mint/v1beta1/genesis.proto b/proto/cosmos/mint/v1beta1/genesis.proto index 4e783fb5448..6d7be3f4e84 100644 --- a/proto/cosmos/mint/v1beta1/genesis.proto +++ b/proto/cosmos/mint/v1beta1/genesis.proto @@ -11,6 +11,12 @@ message GenesisState { // minter is a space for holding current inflation information. Minter minter = 1 [(gogoproto.nullable) = false]; - // params defines all the paramaters of the module. + // params defines all the parameters of the module. + // + // Deprecated: Use governance to submit a MsgUpdateParams message to instruct + // the x/mint module to update the relevant parameters. + // + // Since the cosmos-sdk 0.47 version, this only exists for backwards + // compatibility of genesis state. Params params = 2 [(gogoproto.nullable) = false]; } diff --git a/proto/cosmos/mint/v1beta1/mint.proto b/proto/cosmos/mint/v1beta1/mint.proto index 9cfe2b76076..9835266b759 100644 --- a/proto/cosmos/mint/v1beta1/mint.proto +++ b/proto/cosmos/mint/v1beta1/mint.proto @@ -22,7 +22,7 @@ message Minter { ]; } -// Params holds parameters for the mint module. +// Params defines the parameters for the x/mint module. message Params { option (gogoproto.goproto_stringer) = false; diff --git a/proto/cosmos/mint/v1beta1/tx.proto b/proto/cosmos/mint/v1beta1/tx.proto new file mode 100644 index 00000000000..9c5c7b383db --- /dev/null +++ b/proto/cosmos/mint/v1beta1/tx.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +import "cosmos/msg/v1/msg.proto"; +import "cosmos/mint/v1beta1/mint.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; + +// Msg defines the x/mint Msg service. +service Msg { + // UpdateParams defines a governance operation for updating the x/mint module + // parameters. The authority is hard-coded to the x/gov module account. + // + // Since: cosmos-sdk 0.47 + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade 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/mint 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/x/mint/types/genesis.pb.go b/x/mint/types/genesis.pb.go index 1486c35f223..bb485e18dd4 100644 --- a/x/mint/types/genesis.pb.go +++ b/x/mint/types/genesis.pb.go @@ -27,7 +27,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { // minter is a space for holding current inflation information. Minter Minter `protobuf:"bytes,1,opt,name=minter,proto3" json:"minter"` - // params defines all the paramaters of the module. + // params defines all the parameters of the module. + // + // Deprecated: Use governance to submit a MsgUpdateParams message to instruct + // the x/mint module to update the relevant parameters. + // + // Since the cosmos-sdk 0.47 version, this only exists for backwards + // compatibility of genesis state. Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` } diff --git a/x/mint/types/mint.pb.go b/x/mint/types/mint.pb.go index a5f33f381d3..f2529bdda77 100644 --- a/x/mint/types/mint.pb.go +++ b/x/mint/types/mint.pb.go @@ -66,7 +66,7 @@ func (m *Minter) XXX_DiscardUnknown() { var xxx_messageInfo_Minter proto.InternalMessageInfo -// Params holds parameters for the mint module. +// Params defines the parameters for the x/mint module. type Params struct { // type of coin to mint MintDenom string `protobuf:"bytes,1,opt,name=mint_denom,json=mintDenom,proto3" json:"mint_denom,omitempty"` diff --git a/x/mint/types/tx.pb.go b/x/mint/types/tx.pb.go new file mode 100644 index 00000000000..8e984b9f8fa --- /dev/null +++ b/x/mint/types/tx.pb.go @@ -0,0 +1,603 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/mint/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 + +// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade 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/mint 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_a0d933a8bf5e188a, []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_a0d933a8bf5e188a, []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.mint.v1beta1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.mint.v1beta1.MsgUpdateParamsResponse") +} + +func init() { proto.RegisterFile("cosmos/mint/v1beta1/tx.proto", fileDescriptor_a0d933a8bf5e188a) } + +var fileDescriptor_a0d933a8bf5e188a = []byte{ + // 311 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0xcf, 0xcd, 0xcc, 0x2b, 0xd1, 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, 0xe2, 0x30, 0x2d, 0xc5, 0xe9, 0xfa, 0x65, 0x86, 0x20, 0x0a, 0xa2, 0x5a, 0x4a, + 0x0e, 0x9b, 0x59, 0x60, 0xad, 0x10, 0x79, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, 0x1f, 0xc4, + 0x82, 0x8a, 0x4a, 0x42, 0x74, 0xc5, 0x43, 0x24, 0xa0, 0x16, 0x82, 0x39, 0x4a, 0x53, 0x18, 0xb9, + 0xf8, 0x7d, 0x8b, 0xd3, 0x43, 0x0b, 0x52, 0x12, 0x4b, 0x52, 0x03, 0x12, 0x8b, 0x12, 0x73, 0x8b, + 0x85, 0xcc, 0xb8, 0x38, 0x13, 0x4b, 0x4b, 0x32, 0xf2, 0x8b, 0x32, 0x4b, 0x2a, 0x25, 0x18, 0x15, + 0x18, 0x35, 0x38, 0x9d, 0x24, 0x2e, 0x6d, 0xd1, 0x15, 0x81, 0x6a, 0x74, 0x4c, 0x49, 0x29, 0x4a, + 0x2d, 0x2e, 0x0e, 0x2e, 0x29, 0xca, 0xcc, 0x4b, 0x0f, 0x42, 0x28, 0x15, 0xb2, 0xe4, 0x62, 0x2b, + 0x00, 0x9b, 0x20, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x87, 0xc5, 0x6f, 0x7a, 0x10, + 0x4b, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0x6a, 0xb0, 0xe2, 0x6b, 0x7a, 0xbe, 0x41, + 0x0b, 0x61, 0x94, 0x92, 0x24, 0x97, 0x38, 0x9a, 0xab, 0x82, 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, + 0x53, 0x8d, 0x32, 0xb9, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0x92, 0xb8, 0x78, 0x50, 0x1c, 0xad, 0x82, + 0xd5, 0x32, 0x34, 0x43, 0xa4, 0x74, 0x88, 0x51, 0x05, 0xb3, 0xca, 0xc9, 0xf9, 0xc4, 0x23, 0x39, + 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, + 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x34, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, + 0xf3, 0x73, 0xa1, 0xe1, 0x09, 0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x2b, 0x20, 0xf1, 0x53, 0x52, + 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x0e, 0x68, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, + 0x57, 0x7b, 0xef, 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/mint 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.mint.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/mint 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.mint.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.mint.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/mint/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") +) From caa213beeb800ab2eb3701e2d2221e55d4d5ab02 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:25:19 +0100 Subject: [PATCH 02/21] updates --- x/mint/types/msgs.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 x/mint/types/msgs.go diff --git a/x/mint/types/msgs.go b/x/mint/types/msgs.go new file mode 100644 index 00000000000..2cd99ace200 --- /dev/null +++ b/x/mint/types/msgs.go @@ -0,0 +1,27 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var _ sdk.Msg = &MsgUpdateParams{} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (m *MsgUpdateParams) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(m.Authority) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (m *MsgUpdateParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { + return sdkerrors.Wrap(err, "authority") + } + + if err := m.Params.Validate(); err != nil { + return err + } + + return nil +} From db9e622420d40321406fe7a7fb72ba17554485f4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:25:39 +0100 Subject: [PATCH 03/21] updates --- x/mint/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mint/types/msgs.go b/x/mint/types/msgs.go index 2cd99ace200..e163f45a3fc 100644 --- a/x/mint/types/msgs.go +++ b/x/mint/types/msgs.go @@ -16,7 +16,7 @@ func (m *MsgUpdateParams) GetSigners() []sdk.AccAddress { // ValidateBasic does a sanity check on the provided data. func (m *MsgUpdateParams) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { - return sdkerrors.Wrap(err, "authority") + return sdkerrors.Wrap(err, "invalid authority address") } if err := m.Params.Validate(); err != nil { From e6c571ee87e64c9544fefab44dd4425c1b61d62b Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:38:51 +0100 Subject: [PATCH 04/21] updates --- x/mint/keeper/keeper.go | 57 ++++++++++++++++++++++++----------------- x/mint/types/keys.go | 7 +++-- x/mint/types/params.go | 28 -------------------- 3 files changed, 39 insertions(+), 53 deletions(-) diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 51ade6abef6..5b698e4ca65 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + "cosmossdk.io/math" "github.com/tendermint/tendermint/libs/log" @@ -8,42 +10,43 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mint/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) // Keeper of the mint store type Keeper struct { cdc codec.BinaryCodec storeKey storetypes.StoreKey - paramSpace paramtypes.Subspace stakingKeeper types.StakingKeeper bankKeeper types.BankKeeper feeCollectorName string + + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string } // NewKeeper creates a new mint Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, - sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, + cdc codec.BinaryCodec, + key storetypes.StoreKey, + sk types.StakingKeeper, + ak types.AccountKeeper, + bk types.BankKeeper, feeCollectorName string, + authority string, ) Keeper { // ensure mint module account is set if addr := ak.GetModuleAddress(types.ModuleName); addr == nil { - panic("the mint module account has not been set") - } - - // set KeyTable if it has not already been set - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + panic(fmt.Sprintf("the x/%s module account has not been set", types.ModuleName)) } return Keeper{ cdc: cdc, storeKey: key, - paramSpace: paramSpace, stakingKeeper: sk, bankKeeper: bk, feeCollectorName: feeCollectorName, + authority: authority, } } @@ -55,31 +58,39 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // get the minter func (k Keeper) GetMinter(ctx sdk.Context) (minter types.Minter) { store := ctx.KVStore(k.storeKey) - b := store.Get(types.MinterKey) - if b == nil { + bz := store.Get(types.MinterKey) + if bz == nil { panic("stored minter should not have been nil") } - k.cdc.MustUnmarshal(b, &minter) + k.cdc.MustUnmarshal(bz, &minter) return } // set the minter func (k Keeper) SetMinter(ctx sdk.Context, minter types.Minter) { store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&minter) - store.Set(types.MinterKey, b) + bz := k.cdc.MustMarshal(&minter) + store.Set(types.MinterKey, bz) } -// GetParams returns the total set of minting parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramSpace.GetParamSet(ctx, ¶ms) - return params +// SetParams sets the x/mint module parameters. +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&p) + store.Set(types.ParamsKey, bz) } -// SetParams sets the total set of minting parameters. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramSpace.SetParamSet(ctx, ¶ms) +// GetParams returns the current x/mint module parameters. +func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParamsKey) + if bz == nil { + return p + } + + k.cdc.MustUnmarshal(bz, &p) + return p } // StakingTokenSupply implements an alias call to the underlying staking keeper's diff --git a/x/mint/types/keys.go b/x/mint/types/keys.go index e1c778744f8..dc4699b5a9b 100644 --- a/x/mint/types/keys.go +++ b/x/mint/types/keys.go @@ -1,7 +1,10 @@ package types -// MinterKey is the key to use for the keeper store. -var MinterKey = []byte{0x00} +var ( + // MinterKey is the key to use for the keeper store. + MinterKey = []byte{0x00} + ParamsKey = []byte{0x01} +) const ( // module name diff --git a/x/mint/types/params.go b/x/mint/types/params.go index 56c9b8aa783..6792fefb6bd 100644 --- a/x/mint/types/params.go +++ b/x/mint/types/params.go @@ -8,24 +8,8 @@ import ( "sigs.k8s.io/yaml" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) -// Parameter store keys -var ( - KeyMintDenom = []byte("MintDenom") - KeyInflationRateChange = []byte("InflationRateChange") - KeyInflationMax = []byte("InflationMax") - KeyInflationMin = []byte("InflationMin") - KeyGoalBonded = []byte("GoalBonded") - KeyBlocksPerYear = []byte("BlocksPerYear") -) - -// ParamTable for minting module. -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - func NewParams( mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded sdk.Dec, blocksPerYear uint64, ) Params { @@ -87,18 +71,6 @@ func (p Params) String() string { return string(out) } -// Implements params.ParamSet -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyMintDenom, &p.MintDenom, validateMintDenom), - paramtypes.NewParamSetPair(KeyInflationRateChange, &p.InflationRateChange, validateInflationRateChange), - paramtypes.NewParamSetPair(KeyInflationMax, &p.InflationMax, validateInflationMax), - paramtypes.NewParamSetPair(KeyInflationMin, &p.InflationMin, validateInflationMin), - paramtypes.NewParamSetPair(KeyGoalBonded, &p.GoalBonded, validateGoalBonded), - paramtypes.NewParamSetPair(KeyBlocksPerYear, &p.BlocksPerYear, validateBlocksPerYear), - } -} - func validateMintDenom(i interface{}) error { v, ok := i.(string) if !ok { From 44465dcd7f006747baf86b9f09cb696c3a1e7009 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:48:29 +0100 Subject: [PATCH 05/21] updates --- x/mint/keeper/keeper.go | 13 ++++++++++++- x/mint/keeper/msg_server.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 x/mint/keeper/msg_server.go diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index 5b698e4ca65..af2dc42725f 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -50,6 +50,11 @@ func NewKeeper( } } +// GetAuthority returns the x/mint module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) @@ -75,10 +80,16 @@ func (k Keeper) SetMinter(ctx sdk.Context, minter types.Minter) { } // SetParams sets the x/mint module parameters. -func (k Keeper) SetParams(ctx sdk.Context, p types.Params) { +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error { + if err := p.Validate(); err != nil { + return err + } + store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&p) store.Set(types.ParamsKey, bz) + + return nil } // GetParams returns the current x/mint module parameters. diff --git a/x/mint/keeper/msg_server.go b/x/mint/keeper/msg_server.go new file mode 100644 index 00000000000..128719032e5 --- /dev/null +++ b/x/mint/keeper/msg_server.go @@ -0,0 +1,37 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the upgrade MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(k Keeper) types.MsgServer { + return &msgServer{ + Keeper: k, + } +} + +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 +} From b0a507c63a4acfdcbbc21ee364cac58eaf595022 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 12:53:09 +0100 Subject: [PATCH 06/21] updates --- x/mint/module.go | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/x/mint/module.go b/x/mint/module.go index 5119551ca95..1b040085f53 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -6,11 +6,12 @@ import ( "fmt" "math/rand" + modulev1 "cosmossdk.io/api/cosmos/mint/module/v1" + "cosmossdk.io/core/appmodule" gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -21,15 +22,16 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - - modulev1 "cosmossdk.io/api/cosmos/mint/module/v1" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/mint/client/cli" "github.com/cosmos/cosmos-sdk/x/mint/keeper" "github.com/cosmos/cosmos-sdk/x/mint/simulation" "github.com/cosmos/cosmos-sdk/x/mint/types" ) +// ConsensusVersion defines the current x/mint module consensus version. +const ConsensusVersion = 1 + var ( _ module.AppModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} @@ -135,7 +137,15 @@ 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.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + + // TODO: ... + // m := keeper.NewMigrator(am.keeper) + // err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + // if err != nil { + // panic(err) + // } } // InitGenesis performs genesis initialization for the mint module. It returns @@ -156,7 +166,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion } // BeginBlock returns the begin blocker for the mint module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { @@ -213,9 +223,8 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper { type mintInputs struct { depinject.In - Key *store.KVStoreKey - Cdc codec.Codec - Subspace paramstypes.Subspace + Key *store.KVStoreKey + Cdc codec.Codec AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper @@ -230,7 +239,15 @@ type mintOutputs struct { } func provideModule(in mintInputs) mintOutputs { - k := keeper.NewKeeper(in.Cdc, in.Key, in.Subspace, in.StakingKeeper, in.AccountKeeper, in.BankKeeper, authtypes.FeeCollectorName) + k := keeper.NewKeeper( + in.Cdc, + in.Key, + in.StakingKeeper, + in.AccountKeeper, + in.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) m := NewAppModule(in.Cdc, k, in.AccountKeeper, nil) return mintOutputs{MintKeeper: k, Module: runtime.WrapAppModule(m)} From ad3c88779af099dd8afdc743f0da39b7ad89ad21 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 13:11:38 +0100 Subject: [PATCH 07/21] updates --- x/mint/types/codec.go | 33 +++++++++++++++++++++++++++++++-- x/mint/types/msgs.go | 5 +++++ x/upgrade/types/codec.go | 5 +++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/x/mint/types/codec.go b/x/mint/types/codec.go index a7067d90c2c..74888955356 100644 --- a/x/mint/types/codec.go +++ b/x/mint/types/codec.go @@ -2,12 +2,41 @@ 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" + "github.com/cosmos/cosmos-sdk/types/msgservice" + authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec" ) -var amino = codec.NewLegacyAmino() +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(amino) +) func init() { + RegisterLegacyAminoCodec(amino) cryptocodec.RegisterCrypto(amino) - amino.Seal() + sdk.RegisterLegacyAminoCodec(amino) + + // Register all Amino interfaces and concrete types on the authz Amino codec + // so that this can later be used to properly serialize MsgGrant and MsgExec + // instances. + RegisterLegacyAminoCodec(authzcodec.Amino) +} + +// RegisterLegacyAminoCodec registers concrete types on the LegacyAmino codec +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(Params{}, "cosmos-sdk/x/mint/Params", nil) + legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "cosmos-sdk/x/mint/MsgUpdateParams") +} + +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgUpdateParams{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/mint/types/msgs.go b/x/mint/types/msgs.go index e163f45a3fc..a08186ef312 100644 --- a/x/mint/types/msgs.go +++ b/x/mint/types/msgs.go @@ -7,6 +7,11 @@ import ( var _ sdk.Msg = &MsgUpdateParams{} +// GetSignBytes implements the LegacyMsg interface. +func (m MsgUpdateParams) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + // GetSigners returns the expected signers for a MsgUpdateParams message. func (m *MsgUpdateParams) GetSigners() []sdk.AccAddress { addr, _ := sdk.AccAddressFromBech32(m.Authority) diff --git a/x/upgrade/types/codec.go b/x/upgrade/types/codec.go index 0f852cc9a2a..91f9531a132 100644 --- a/x/upgrade/types/codec.go +++ b/x/upgrade/types/codec.go @@ -45,7 +45,8 @@ func init() { cryptocodec.RegisterCrypto(amino) sdk.RegisterLegacyAminoCodec(amino) - // Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be - // used to properly serialize MsgGrant and MsgExec instances + // Register all Amino interfaces and concrete types on the authz Amino codec + // so that this can later be used to properly serialize MsgGrant and MsgExec + // instances. RegisterLegacyAminoCodec(authzcodec.Amino) } From 4165e1fb9161d543f58c8eab20e357350a1c4601 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 10:44:14 -0400 Subject: [PATCH 08/21] Update proto/cosmos/mint/v1beta1/tx.proto Co-authored-by: Anil Kumar Kammari --- proto/cosmos/mint/v1beta1/tx.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/cosmos/mint/v1beta1/tx.proto b/proto/cosmos/mint/v1beta1/tx.proto index 9c5c7b383db..982a4232efc 100644 --- a/proto/cosmos/mint/v1beta1/tx.proto +++ b/proto/cosmos/mint/v1beta1/tx.proto @@ -17,7 +17,7 @@ service Msg { rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } -// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade request type. +// MsgUpdateParams is the Msg/UpdateParams request type. // // Since: cosmos-sdk 0.47 message MsgUpdateParams { From b1333e504101ec0bdfe84b0aff565436558dac5c Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 27 Jun 2022 17:55:55 +0100 Subject: [PATCH 09/21] updates --- x/mint/keeper/keeper_test.go | 83 ++++++++++++++++++++++++++++++++ x/mint/keeper/migrator.go | 25 ++++++++++ x/mint/keeper/msg_server_test.go | 1 + x/mint/module.go | 44 ++++++++++++----- x/mint/types/params.go | 6 +-- x/mint/types/params_legacy.go | 41 ++++++++++++++++ 6 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 x/mint/keeper/keeper_test.go create mode 100644 x/mint/keeper/migrator.go create mode 100644 x/mint/keeper/msg_server_test.go create mode 100644 x/mint/types/params_legacy.go diff --git a/x/mint/keeper/keeper_test.go b/x/mint/keeper/keeper_test.go new file mode 100644 index 00000000000..7c292a12b71 --- /dev/null +++ b/x/mint/keeper/keeper_test.go @@ -0,0 +1,83 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +type IntegrationTestSuite struct { + suite.Suite + + app *simapp.SimApp + ctx sdk.Context +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (s *IntegrationTestSuite) SetupTest() { + app := simapp.Setup(s.T(), false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + + s.app = app + s.ctx = ctx +} + +func (s *IntegrationTestSuite) TestParams() { + testCases := []struct { + name string + input types.Params + expectErr bool + }{ + { + name: "set invalid params", + input: types.Params{ + MintDenom: sdk.DefaultBondDenom, + InflationRateChange: sdk.NewDecWithPrec(-13, 2), + InflationMax: sdk.NewDecWithPrec(20, 2), + InflationMin: sdk.NewDecWithPrec(7, 2), + GoalBonded: sdk.NewDecWithPrec(67, 2), + BlocksPerYear: uint64(60 * 60 * 8766 / 5), + }, + expectErr: true, + }, + { + name: "set full valid params", + input: types.Params{ + MintDenom: sdk.DefaultBondDenom, + InflationRateChange: sdk.NewDecWithPrec(8, 2), + InflationMax: sdk.NewDecWithPrec(20, 2), + InflationMin: sdk.NewDecWithPrec(2, 2), + GoalBonded: sdk.NewDecWithPrec(37, 2), + BlocksPerYear: uint64(60 * 60 * 8766 / 5), + }, + expectErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + expected := s.app.MintKeeper.GetParams(s.ctx) + err := s.app.MintKeeper.SetParams(s.ctx, tc.input) + if tc.expectErr { + s.Require().Error(err) + } else { + expected = tc.input + s.Require().NoError(err) + } + + p := s.app.MintKeeper.GetParams(s.ctx) + s.Require().Equal(expected, p) + }) + } +} diff --git a/x/mint/keeper/migrator.go b/x/mint/keeper/migrator.go new file mode 100644 index 00000000000..696153bbfe6 --- /dev/null +++ b/x/mint/keeper/migrator.go @@ -0,0 +1,25 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Migrator is a struct for handling in-place state migrations. +type Migrator struct { + keeper Keeper + + legacySubspace paramstypes.Subspace +} + +func NewMigrator(keeper Keeper, ss paramstypes.Subspace) Migrator { + return Migrator{ + keeper: keeper, + legacySubspace: ss, + } +} + +// Migrate1to2 migrates from version 1 to 2. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + panic("implement me!") +} diff --git a/x/mint/keeper/msg_server_test.go b/x/mint/keeper/msg_server_test.go new file mode 100644 index 00000000000..9429264902a --- /dev/null +++ b/x/mint/keeper/msg_server_test.go @@ -0,0 +1 @@ +package keeper_test diff --git a/x/mint/module.go b/x/mint/module.go index 1b040085f53..16c0922da9a 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -27,10 +27,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/mint/keeper" "github.com/cosmos/cosmos-sdk/x/mint/simulation" "github.com/cosmos/cosmos-sdk/x/mint/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" ) // ConsensusVersion defines the current x/mint module consensus version. -const ConsensusVersion = 1 +const ConsensusVersion = 2 var ( _ module.AppModule = AppModule{} @@ -51,10 +52,14 @@ func (AppModuleBasic) Name() string { } // RegisterLegacyAminoCodec registers the mint module's types on the given LegacyAmino codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} // RegisterInterfaces registers the module's interface types -func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} +func (b AppModuleBasic) RegisterInterfaces(r cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(r) +} // DefaultGenesis returns default genesis state as raw bytes for the mint // module. @@ -94,6 +99,9 @@ type AppModule struct { keeper keeper.Keeper authKeeper types.AccountKeeper + // legacySubspace is used solely for migration of x/params managed parameters + legacySubspace paramstypes.Subspace + // inflationCalculator is used to calculate the inflation rate during BeginBlock. // If inflationCalculator is nil, the default inflation calculation logic is used. inflationCalculator types.InflationCalculationFn @@ -101,15 +109,23 @@ type AppModule struct { // NewAppModule creates a new AppModule object. If the InflationCalculationFn // argument is nil, then the SDK's default inflation function will be used. -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper, ic types.InflationCalculationFn) AppModule { +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, + ak types.AccountKeeper, + ic types.InflationCalculationFn, + ss paramstypes.Subspace, +) AppModule { if ic == nil { ic = types.DefaultInflationCalculationFn } + return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, authKeeper: ak, inflationCalculator: ic, + legacySubspace: ss, } } @@ -140,12 +156,11 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) - // TODO: ... - // m := keeper.NewMigrator(am.keeper) - // err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) - // if err != nil { - // panic(err) - // } + m := keeper.NewMigrator(am.keeper, am.legacySubspace) + err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + if err != nil { + panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the mint module. It returns @@ -206,9 +221,9 @@ func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.Weighte return nil } -// +// ============================================================================ // New App Wiring Setup -// +// ============================================================================ func init() { appmodule.Register(&modulev1.Module{}, @@ -226,6 +241,9 @@ type mintInputs struct { Key *store.KVStoreKey Cdc codec.Codec + // LegacySubspace is used solely for migration of x/params managed parameters + LegacySubspace paramstypes.Subspace + AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper StakingKeeper types.StakingKeeper @@ -248,7 +266,7 @@ func provideModule(in mintInputs) mintOutputs { authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - m := NewAppModule(in.Cdc, k, in.AccountKeeper, nil) + m := NewAppModule(in.Cdc, k, in.AccountKeeper, nil, in.LegacySubspace) return mintOutputs{MintKeeper: k, Module: runtime.WrapAppModule(m)} } diff --git a/x/mint/types/params.go b/x/mint/types/params.go index 6792fefb6bd..34b0b38510e 100644 --- a/x/mint/types/params.go +++ b/x/mint/types/params.go @@ -10,9 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func NewParams( - mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded sdk.Dec, blocksPerYear uint64, -) Params { +func NewParams(mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded sdk.Dec, blocksPerYear uint64) Params { return Params{ MintDenom: mintDenom, InflationRateChange: inflationRateChange, @@ -23,7 +21,7 @@ func NewParams( } } -// default minting module parameters +// DefaultParams returns default x/mint module parameters. func DefaultParams() Params { return Params{ MintDenom: sdk.DefaultBondDenom, diff --git a/x/mint/types/params_legacy.go b/x/mint/types/params_legacy.go new file mode 100644 index 00000000000..ad44e9f0299 --- /dev/null +++ b/x/mint/types/params_legacy.go @@ -0,0 +1,41 @@ +/* +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. +*/ +package types + +import ( + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter store keys +var ( + KeyMintDenom = []byte("MintDenom") + KeyInflationRateChange = []byte("InflationRateChange") + KeyInflationMax = []byte("InflationMax") + KeyInflationMin = []byte("InflationMin") + KeyGoalBonded = []byte("GoalBonded") + KeyBlocksPerYear = []byte("BlocksPerYear") +) + +// ParamTable for minting module. +// +// NOTE: Deprecated. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// Implements params.ParamSet +// +// NOTE: Deprecated. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyMintDenom, &p.MintDenom, validateMintDenom), + paramtypes.NewParamSetPair(KeyInflationRateChange, &p.InflationRateChange, validateInflationRateChange), + paramtypes.NewParamSetPair(KeyInflationMax, &p.InflationMax, validateInflationMax), + paramtypes.NewParamSetPair(KeyInflationMin, &p.InflationMin, validateInflationMin), + paramtypes.NewParamSetPair(KeyGoalBonded, &p.GoalBonded, validateGoalBonded), + paramtypes.NewParamSetPair(KeyBlocksPerYear, &p.BlocksPerYear, validateBlocksPerYear), + } +} From b10bb3407f9f66e3f86ebc9b78d3cf4a840d01c2 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jun 2022 22:20:46 +0100 Subject: [PATCH 10/21] updates --- x/mint/keeper/keeper_test.go | 7 +++- x/mint/keeper/msg_server.go | 3 +- x/mint/keeper/msg_server_test.go | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/x/mint/keeper/keeper_test.go b/x/mint/keeper/keeper_test.go index 7c292a12b71..79c97ea2c34 100644 --- a/x/mint/keeper/keeper_test.go +++ b/x/mint/keeper/keeper_test.go @@ -9,14 +9,16 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint/keeper" "github.com/cosmos/cosmos-sdk/x/mint/types" ) type IntegrationTestSuite struct { suite.Suite - app *simapp.SimApp - ctx sdk.Context + app *simapp.SimApp + ctx sdk.Context + msgServer types.MsgServer } func TestKeeperTestSuite(t *testing.T) { @@ -29,6 +31,7 @@ func (s *IntegrationTestSuite) SetupTest() { s.app = app s.ctx = ctx + s.msgServer = keeper.NewMsgServerImpl(s.app.MintKeeper) } func (s *IntegrationTestSuite) TestParams() { diff --git a/x/mint/keeper/msg_server.go b/x/mint/keeper/msg_server.go index 128719032e5..ff879cc2897 100644 --- a/x/mint/keeper/msg_server.go +++ b/x/mint/keeper/msg_server.go @@ -15,8 +15,7 @@ type msgServer struct { Keeper } -// NewMsgServerImpl returns an implementation of the upgrade MsgServer interface -// for the provided Keeper. +// NewMsgServerImpl returns an implementation of the x/mint MsgServer interface. func NewMsgServerImpl(k Keeper) types.MsgServer { return &msgServer{ Keeper: k, diff --git a/x/mint/keeper/msg_server_test.go b/x/mint/keeper/msg_server_test.go index 9429264902a..1db143fca4d 100644 --- a/x/mint/keeper/msg_server_test.go +++ b/x/mint/keeper/msg_server_test.go @@ -1 +1,64 @@ package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +func (s *IntegrationTestSuite) TestUpdateParams() { + testCases := []struct { + name string + request *types.MsgUpdateParams + expectErr bool + }{ + { + name: "set invalid authority", + request: &types.MsgUpdateParams{ + Authority: "foo", + }, + expectErr: true, + }, + { + name: "set invalid params", + request: &types.MsgUpdateParams{ + Authority: s.app.MintKeeper.GetAuthority(), + Params: types.Params{ + MintDenom: sdk.DefaultBondDenom, + InflationRateChange: sdk.NewDecWithPrec(-13, 2), + InflationMax: sdk.NewDecWithPrec(20, 2), + InflationMin: sdk.NewDecWithPrec(7, 2), + GoalBonded: sdk.NewDecWithPrec(67, 2), + BlocksPerYear: uint64(60 * 60 * 8766 / 5), + }, + }, + expectErr: true, + }, + { + name: "set full valid params", + request: &types.MsgUpdateParams{ + Authority: s.app.MintKeeper.GetAuthority(), + Params: types.Params{ + MintDenom: sdk.DefaultBondDenom, + InflationRateChange: sdk.NewDecWithPrec(8, 2), + InflationMax: sdk.NewDecWithPrec(20, 2), + InflationMin: sdk.NewDecWithPrec(2, 2), + GoalBonded: sdk.NewDecWithPrec(37, 2), + BlocksPerYear: uint64(60 * 60 * 8766 / 5), + }, + }, + expectErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + _, err := s.msgServer.UpdateParams(s.ctx, tc.request) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + } + }) + } +} From a732e8df7b66ec17dc01ae663922f305969377f4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jun 2022 22:23:22 +0100 Subject: [PATCH 11/21] updates --- x/mint/types/params_legacy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mint/types/params_legacy.go b/x/mint/types/params_legacy.go index ad44e9f0299..d9e5b17991d 100644 --- a/x/mint/types/params_legacy.go +++ b/x/mint/types/params_legacy.go @@ -1,7 +1,7 @@ /* 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. +for migration purposes and will be removed in a future release. */ package types From e0c21c21a734c0094e4177734c701a367d0c5312 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 29 Jun 2022 00:14:19 +0100 Subject: [PATCH 12/21] updates --- x/mint/keeper/migrator.go | 25 ------------------------- x/mint/migrator/migrator.go | 33 +++++++++++++++++++++++++++++++++ x/mint/module.go | 7 ++++--- 3 files changed, 37 insertions(+), 28 deletions(-) delete mode 100644 x/mint/keeper/migrator.go create mode 100644 x/mint/migrator/migrator.go diff --git a/x/mint/keeper/migrator.go b/x/mint/keeper/migrator.go deleted file mode 100644 index 696153bbfe6..00000000000 --- a/x/mint/keeper/migrator.go +++ /dev/null @@ -1,25 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" -) - -// Migrator is a struct for handling in-place state migrations. -type Migrator struct { - keeper Keeper - - legacySubspace paramstypes.Subspace -} - -func NewMigrator(keeper Keeper, ss paramstypes.Subspace) Migrator { - return Migrator{ - keeper: keeper, - legacySubspace: ss, - } -} - -// Migrate1to2 migrates from version 1 to 2. -func (m Migrator) Migrate1to2(ctx sdk.Context) error { - panic("implement me!") -} diff --git a/x/mint/migrator/migrator.go b/x/mint/migrator/migrator.go new file mode 100644 index 00000000000..6281131bbf2 --- /dev/null +++ b/x/mint/migrator/migrator.go @@ -0,0 +1,33 @@ +package migrator + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint/keeper" + "github.com/cosmos/cosmos-sdk/x/mint/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Migrator is a struct for handling in-place state migrations. +type Migrator struct { + keeper keeper.Keeper + legacySubspace paramstypes.Subspace +} + +func New(k keeper.Keeper, ss paramstypes.Subspace) Migrator { + return Migrator{ + keeper: k, + legacySubspace: ss, + } +} + +// Migrate1to2 migrates the x/mint module state from the consensus version 1 to +// version 2. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the x/mint +// module state. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + var currParams types.Params + m.legacySubspace.GetParamSet(ctx, &currParams) + + return m.keeper.SetParams(ctx, currParams) + +} diff --git a/x/mint/module.go b/x/mint/module.go index 16c0922da9a..33de54de977 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -25,6 +25,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/mint/client/cli" "github.com/cosmos/cosmos-sdk/x/mint/keeper" + "github.com/cosmos/cosmos-sdk/x/mint/migrator" "github.com/cosmos/cosmos-sdk/x/mint/simulation" "github.com/cosmos/cosmos-sdk/x/mint/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -156,9 +157,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) - m := keeper.NewMigrator(am.keeper, am.legacySubspace) - err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) - if err != nil { + m := migrator.New(am.keeper, am.legacySubspace) + + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err)) } } From e59470a171fbc80748000cb2eb660419ff50d525 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 29 Jun 2022 00:15:08 +0100 Subject: [PATCH 13/21] updates --- x/mint/migrator/migrator.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/mint/migrator/migrator.go b/x/mint/migrator/migrator.go index 6281131bbf2..8bdf53c7170 100644 --- a/x/mint/migrator/migrator.go +++ b/x/mint/migrator/migrator.go @@ -29,5 +29,4 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { m.legacySubspace.GetParamSet(ctx, &currParams) return m.keeper.SetParams(ctx, currParams) - } From d66c71f72719fc0aefeab2ea77d3c31fbe57585c Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 29 Jun 2022 17:34:56 +0100 Subject: [PATCH 14/21] updates --- types/module/testutil/codec.go | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 types/module/testutil/codec.go diff --git a/types/module/testutil/codec.go b/types/module/testutil/codec.go new file mode 100644 index 00000000000..8a4fd78a0a4 --- /dev/null +++ b/types/module/testutil/codec.go @@ -0,0 +1,39 @@ +package testutil + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/tx" +) + +type TestEncodingConfig struct { + InterfaceRegistry types.InterfaceRegistry + Codec codec.Codec + TxConfig client.TxConfig + Amino *codec.LegacyAmino +} + +func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig { + cdc := codec.NewLegacyAmino() + interfaceRegistry := types.NewInterfaceRegistry() + codec := codec.NewProtoCodec(interfaceRegistry) + + encCfg := TestEncodingConfig{ + InterfaceRegistry: interfaceRegistry, + Codec: codec, + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), + Amino: cdc, + } + + mb := module.NewBasicManager(modules...) + + std.RegisterLegacyAminoCodec(encCfg.Amino) + std.RegisterInterfaces(encCfg.InterfaceRegistry) + mb.RegisterLegacyAminoCodec(encCfg.Amino) + mb.RegisterInterfaces(encCfg.InterfaceRegistry) + + return encCfg +} From 27a71a58ad1d1a3420153cecce20e84051e4632b Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 11:42:31 +0100 Subject: [PATCH 15/21] updates --- types/module/testutil/codec.go | 4 +++ x/mint/exported/exported.go | 24 +++++++++++++ x/mint/{migrator => keeper}/migrator.go | 18 ++++------ x/mint/migrations/v2/migrate.go | 39 +++++++++++++++++++++ x/mint/migrations/v2/migrator_test.go | 45 +++++++++++++++++++++++++ x/mint/module.go | 11 +++--- 6 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 x/mint/exported/exported.go rename x/mint/{migrator => keeper}/migrator.go (55%) create mode 100644 x/mint/migrations/v2/migrate.go create mode 100644 x/mint/migrations/v2/migrator_test.go diff --git a/types/module/testutil/codec.go b/types/module/testutil/codec.go index 8a4fd78a0a4..b54085c584e 100644 --- a/types/module/testutil/codec.go +++ b/types/module/testutil/codec.go @@ -9,6 +9,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/tx" ) +// TestEncodingConfig defines an encoding configuration that is used for testing +// purposes. Note, MakeTestEncodingConfig takes a series of AppModuleBasic types +// which should only contain the relevant module being tested and any potential +// dependencies. type TestEncodingConfig struct { InterfaceRegistry types.InterfaceRegistry Codec codec.Codec diff --git a/x/mint/exported/exported.go b/x/mint/exported/exported.go new file mode 100644 index 00000000000..82ab53b591e --- /dev/null +++ b/x/mint/exported/exported.go @@ -0,0 +1,24 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +type ( + // ParamSet defines an interface that implements the legacy x/params ParamSet + // type. + // + // NOTE: This is used solely for migration of x/params managed parameters. + ParamSet interface { + ParamSetPairs() paramtypes.ParamSetPairs + } + + // 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/mint/migrator/migrator.go b/x/mint/keeper/migrator.go similarity index 55% rename from x/mint/migrator/migrator.go rename to x/mint/keeper/migrator.go index 8bdf53c7170..68d72962120 100644 --- a/x/mint/migrator/migrator.go +++ b/x/mint/keeper/migrator.go @@ -1,19 +1,18 @@ -package migrator +package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/mint/keeper" - "github.com/cosmos/cosmos-sdk/x/mint/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/mint/exported" + v2 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v2" ) // Migrator is a struct for handling in-place state migrations. type Migrator struct { - keeper keeper.Keeper - legacySubspace paramstypes.Subspace + keeper Keeper + legacySubspace exported.Subspace } -func New(k keeper.Keeper, ss paramstypes.Subspace) Migrator { +func NewMigrator(k Keeper, ss exported.Subspace) Migrator { return Migrator{ keeper: k, legacySubspace: ss, @@ -25,8 +24,5 @@ func New(k keeper.Keeper, ss paramstypes.Subspace) Migrator { // and managed by the x/params modules and stores them directly into the x/mint // module state. func (m Migrator) Migrate1to2(ctx sdk.Context) error { - var currParams types.Params - m.legacySubspace.GetParamSet(ctx, &currParams) - - return m.keeper.SetParams(ctx, currParams) + return v2.Migrate(ctx, ctx.KVStore(m.keeper.storeKey), m.legacySubspace, m.keeper.cdc) } diff --git a/x/mint/migrations/v2/migrate.go b/x/mint/migrations/v2/migrate.go new file mode 100644 index 00000000000..2589eb3fd5c --- /dev/null +++ b/x/mint/migrations/v2/migrate.go @@ -0,0 +1,39 @@ +package v2 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mint/exported" + "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +const ( + ModuleName = "mint" +) + +var ( + ParamsKey = []byte{0x01} +) + +// Migrate migrates the x/mint module state from the consensus version 1 to +// version 2. Specifically, it takes the parameters that are currently stored +// and managed by the x/params modules and stores them directly into the x/mint +// 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/mint/migrations/v2/migrator_test.go b/x/mint/migrations/v2/migrator_test.go new file mode 100644 index 00000000000..86f27ee2e67 --- /dev/null +++ b/x/mint/migrations/v2/migrator_test.go @@ -0,0 +1,45 @@ +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/mint" + "github.com/cosmos/cosmos-sdk/x/mint/exported" + v2 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v2" + "github.com/cosmos/cosmos-sdk/x/mint/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(mint.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/mint/module.go b/x/mint/module.go index 33de54de977..a574f921eab 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -24,11 +24,10 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/mint/client/cli" + "github.com/cosmos/cosmos-sdk/x/mint/exported" "github.com/cosmos/cosmos-sdk/x/mint/keeper" - "github.com/cosmos/cosmos-sdk/x/mint/migrator" "github.com/cosmos/cosmos-sdk/x/mint/simulation" "github.com/cosmos/cosmos-sdk/x/mint/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" ) // ConsensusVersion defines the current x/mint module consensus version. @@ -101,7 +100,7 @@ type AppModule struct { authKeeper types.AccountKeeper // legacySubspace is used solely for migration of x/params managed parameters - legacySubspace paramstypes.Subspace + legacySubspace exported.Subspace // inflationCalculator is used to calculate the inflation rate during BeginBlock. // If inflationCalculator is nil, the default inflation calculation logic is used. @@ -115,7 +114,7 @@ func NewAppModule( keeper keeper.Keeper, ak types.AccountKeeper, ic types.InflationCalculationFn, - ss paramstypes.Subspace, + ss exported.Subspace, ) AppModule { if ic == nil { ic = types.DefaultInflationCalculationFn @@ -157,7 +156,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) - m := migrator.New(am.keeper, am.legacySubspace) + m := keeper.NewMigrator(am.keeper, am.legacySubspace) if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err)) @@ -243,7 +242,7 @@ type mintInputs struct { Cdc codec.Codec // LegacySubspace is used solely for migration of x/params managed parameters - LegacySubspace paramstypes.Subspace + LegacySubspace exported.Subspace AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper From 6b87e08d1b8fab2a7dc7812e6c07e8009f2e97a8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 11:57:07 +0100 Subject: [PATCH 16/21] updates --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5d4ab03257..4a777b545e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,9 +48,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#12153](https://github.com/cosmos/cosmos-sdk/pull/12153) Add a new `NewSimulationManagerFromAppModules` constructor, to simplify simulation wiring. * [#12187](https://github.com/cosmos/cosmos-sdk/pull/12187) Add batch operation for x/nft module. +### State Machine Breaking + +* (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`. + ### API Breaking Changes -* (simapp) [#XXXXX](https://github.com/cosmos/cosmos-sdk/pull/XXXXX) Move `simapp.ConvertAddrsToValAddrs` and `simapp.CreateTestPubKeys ` to respectively `simtestutil.ConvertAddrsToValAddrs` and `simtestutil.CreateTestPubKeys` (`testutil/sims`) +* (simapp) [#12334](https://github.com/cosmos/cosmos-sdk/pull/12334) Move `simapp.ConvertAddrsToValAddrs` and `simapp.CreateTestPubKeys ` to respectively `simtestutil.ConvertAddrsToValAddrs` and `simtestutil.CreateTestPubKeys` (`testutil/sims`) * (simapp) [#12312](https://github.com/cosmos/cosmos-sdk/pull/12312) Move `simapp.EmptyAppOptions` to `simtestutil.EmptyAppOptions` (`testutil/sims`) * (simapp) [#12312](https://github.com/cosmos/cosmos-sdk/pull/12312) Remove `skipUpgradeHeights map[int64]bool` and `homePath string` from `NewSimApp` constructor as per migration of `x/upgrade` to app-wiring. * (testutil) [#12278](https://github.com/cosmos/cosmos-sdk/pull/12278) Move all functions from `simapp/helpers` to `testutil/sims` From 2b54f1b54bad647aa43d332fcc63fd01263b7cee Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 12:01:03 +0100 Subject: [PATCH 17/21] updates --- api/cosmos/mint/v1beta1/genesis.pulsar.go | 6 ------ api/cosmos/mint/v1beta1/tx.pulsar.go | 2 +- proto/cosmos/mint/v1beta1/genesis.proto | 6 ------ x/mint/types/genesis.pb.go | 6 ------ x/mint/types/tx.pb.go | 2 +- 5 files changed, 2 insertions(+), 20 deletions(-) diff --git a/api/cosmos/mint/v1beta1/genesis.pulsar.go b/api/cosmos/mint/v1beta1/genesis.pulsar.go index 22e05176567..1afa792e275 100644 --- a/api/cosmos/mint/v1beta1/genesis.pulsar.go +++ b/api/cosmos/mint/v1beta1/genesis.pulsar.go @@ -549,12 +549,6 @@ type GenesisState struct { // minter is a space for holding current inflation information. Minter *Minter `protobuf:"bytes,1,opt,name=minter,proto3" json:"minter,omitempty"` // params defines all the parameters of the module. - // - // Deprecated: Use governance to submit a MsgUpdateParams message to instruct - // the x/mint module to update the relevant parameters. - // - // Since the cosmos-sdk 0.47 version, this only exists for backwards - // compatibility of genesis state. Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` } diff --git a/api/cosmos/mint/v1beta1/tx.pulsar.go b/api/cosmos/mint/v1beta1/tx.pulsar.go index 28b6f60b859..17b7a59c6fe 100644 --- a/api/cosmos/mint/v1beta1/tx.pulsar.go +++ b/api/cosmos/mint/v1beta1/tx.pulsar.go @@ -883,7 +883,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade request type. +// MsgUpdateParams is the Msg/UpdateParams request type. // // Since: cosmos-sdk 0.47 type MsgUpdateParams struct { diff --git a/proto/cosmos/mint/v1beta1/genesis.proto b/proto/cosmos/mint/v1beta1/genesis.proto index 6d7be3f4e84..30199d1ddb2 100644 --- a/proto/cosmos/mint/v1beta1/genesis.proto +++ b/proto/cosmos/mint/v1beta1/genesis.proto @@ -12,11 +12,5 @@ message GenesisState { Minter minter = 1 [(gogoproto.nullable) = false]; // params defines all the parameters of the module. - // - // Deprecated: Use governance to submit a MsgUpdateParams message to instruct - // the x/mint module to update the relevant parameters. - // - // Since the cosmos-sdk 0.47 version, this only exists for backwards - // compatibility of genesis state. Params params = 2 [(gogoproto.nullable) = false]; } diff --git a/x/mint/types/genesis.pb.go b/x/mint/types/genesis.pb.go index bb485e18dd4..107011974d8 100644 --- a/x/mint/types/genesis.pb.go +++ b/x/mint/types/genesis.pb.go @@ -28,12 +28,6 @@ type GenesisState struct { // minter is a space for holding current inflation information. Minter Minter `protobuf:"bytes,1,opt,name=minter,proto3" json:"minter"` // params defines all the parameters of the module. - // - // Deprecated: Use governance to submit a MsgUpdateParams message to instruct - // the x/mint module to update the relevant parameters. - // - // Since the cosmos-sdk 0.47 version, this only exists for backwards - // compatibility of genesis state. Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` } diff --git a/x/mint/types/tx.pb.go b/x/mint/types/tx.pb.go index 8e984b9f8fa..f43d9e7b1e4 100644 --- a/x/mint/types/tx.pb.go +++ b/x/mint/types/tx.pb.go @@ -30,7 +30,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// MsgSoftwareUpgrade is the Msg/SoftwareUpgrade request type. +// MsgUpdateParams is the Msg/UpdateParams request type. // // Since: cosmos-sdk 0.47 type MsgUpdateParams struct { From ba334c8f38f447344fc218b8facd3a55bdd23e6f Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 17:50:11 +0100 Subject: [PATCH 18/21] updates --- CHANGELOG.md | 2 +- api/cosmos/crisis/module/v1/module.pulsar.go | 578 ++++++++++++++++++ .../distribution/module/v1/module.pulsar.go | 122 +++- api/cosmos/mint/module/v1/module.pulsar.go | 114 +++- baseapp/block_gas_test.go | 2 +- depinject/README.md | 8 +- docs/architecture/adr-038-state-listening.md | 3 +- proto/cosmos/crisis/module/v1/module.proto | 14 + .../distribution/module/v1/module.proto | 2 + proto/cosmos/mint/module/v1/module.proto | 2 + server/README.md | 1 - server/export_test.go | 6 +- simapp/app.go | 21 +- simapp/app_config.go | 5 + simapp/app_test.go | 24 +- simapp/sim_bench_test.go | 14 +- simapp/sim_test.go | 30 +- simapp/simd/cmd/root.go | 15 +- simapp/test_helpers.go | 20 +- testutil/network/network.go | 2 +- testutil/sims/app_helpers.go | 7 +- x/auth/tx/module/module.go | 6 +- x/crisis/keeper/genesis.go | 4 +- x/crisis/keeper/keeper.go | 16 +- x/crisis/keeper/msg_server.go | 4 +- x/crisis/keeper/params.go | 4 +- x/crisis/module.go | 64 +- x/distribution/module.go | 8 +- x/gov/genesis_test.go | 2 +- x/gov/module_test.go | 9 +- x/mint/module.go | 14 +- x/slashing/module.go | 6 +- x/staking/module_test.go | 9 +- 33 files changed, 1004 insertions(+), 134 deletions(-) create mode 100644 api/cosmos/crisis/module/v1/module.pulsar.go create mode 100644 proto/cosmos/crisis/module/v1/module.proto diff --git a/CHANGELOG.md b/CHANGELOG.md index 7835ae9f41e..402332ca14c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* (cli) [#12028](https://github.com/cosmos/cosmos-sdk/pull/12028) Add the `tendermint key-migrate` to perform Tendermint v0.35 DB key migration. +* (cli) [#12028](https://github.com/cosmos/cosmos-sdk/pull/12028) Add the `tendermint key-migrate` to perform Tendermint v0.35 DB key migration.12363 * (query) [#12253](https://github.com/cosmos/cosmos-sdk/pull/12253) Add `GenericFilteredPaginate` to the `query` package to improve UX. ### Improvements diff --git a/api/cosmos/crisis/module/v1/module.pulsar.go b/api/cosmos/crisis/module/v1/module.pulsar.go new file mode 100644 index 00000000000..f5a0eee0d22 --- /dev/null +++ b/api/cosmos/crisis/module/v1/module.pulsar.go @@ -0,0 +1,578 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package modulev1 + +import ( + _ "cosmossdk.io/api/cosmos/app/v1alpha1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + 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_Module protoreflect.MessageDescriptor + fd_Module_fee_collector_name protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_crisis_module_v1_module_proto_init() + md_Module = File_cosmos_crisis_module_v1_module_proto.Messages().ByName("Module") + fd_Module_fee_collector_name = md_Module.Fields().ByName("fee_collector_name") +} + +var _ protoreflect.Message = (*fastReflection_Module)(nil) + +type fastReflection_Module Module + +func (x *Module) ProtoReflect() protoreflect.Message { + return (*fastReflection_Module)(x) +} + +func (x *Module) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_crisis_module_v1_module_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_Module_messageType fastReflection_Module_messageType +var _ protoreflect.MessageType = fastReflection_Module_messageType{} + +type fastReflection_Module_messageType struct{} + +func (x fastReflection_Module_messageType) Zero() protoreflect.Message { + return (*fastReflection_Module)(nil) +} +func (x fastReflection_Module_messageType) New() protoreflect.Message { + return new(fastReflection_Module) +} +func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// 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_Module) Type() protoreflect.MessageType { + return _fastReflection_Module_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Module) New() protoreflect.Message { + return new(fastReflection_Module) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { + return (*Module)(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_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.FeeCollectorName != "" { + value := protoreflect.ValueOfString(x.FeeCollectorName) + if !f(fd_Module_fee_collector_name, 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_Module) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + return x.FeeCollectorName != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + x.FeeCollectorName = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + value := x.FeeCollectorName + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + x.FeeCollectorName = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + panic(fmt.Errorf("field fee_collector_name of message cosmos.crisis.module.v1.Module is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.crisis.module.v1.Module.fee_collector_name": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.crisis.module.v1.Module")) + } + panic(fmt.Errorf("message cosmos.crisis.module.v1.Module 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_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.crisis.module.v1.Module", 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_Module) 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_Module) 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_Module) 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_Module) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Module) + 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.FeeCollectorName) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.FeeCollectorName) > 0 { + i -= len(x.FeeCollectorName) + copy(dAtA[i:], x.FeeCollectorName) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.FeeCollectorName))) + 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().(*Module) + 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: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: 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 FeeCollectorName", 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.FeeCollectorName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: cosmos/crisis/module/v1/module.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) +) + +// Module is the config object of the crisis module. +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FeeCollectorName string `protobuf:"bytes,1,opt,name=fee_collector_name,json=feeCollectorName,proto3" json:"fee_collector_name,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_crisis_module_v1_module_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_cosmos_crisis_module_v1_module_proto_rawDescGZIP(), []int{0} +} + +func (x *Module) GetFeeCollectorName() string { + if x != nil { + return x.FeeCollectorName + } + return "" +} + +var File_cosmos_crisis_module_v1_module_proto protoreflect.FileDescriptor + +var file_cosmos_crisis_module_v1_module_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x2f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, + 0x72, 0x69, 0x73, 0x69, 0x73, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, + 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x65, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, + 0x65, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x65, 0x65, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x2d, 0xba, 0xc0, 0x96, 0xda, 0x01, + 0x27, 0x0a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, + 0x78, 0x2f, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x42, 0xdc, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x2e, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x63, 0x72, 0x69, 0x73, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, + 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x43, 0x4d, + 0xaa, 0x02, 0x17, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x73, 0x69, 0x73, + 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x17, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x5c, 0x43, 0x72, 0x69, 0x73, 0x69, 0x73, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x23, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x43, 0x72, + 0x69, 0x73, 0x69, 0x73, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x43, 0x72, 0x69, 0x73, 0x69, 0x73, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_crisis_module_v1_module_proto_rawDescOnce sync.Once + file_cosmos_crisis_module_v1_module_proto_rawDescData = file_cosmos_crisis_module_v1_module_proto_rawDesc +) + +func file_cosmos_crisis_module_v1_module_proto_rawDescGZIP() []byte { + file_cosmos_crisis_module_v1_module_proto_rawDescOnce.Do(func() { + file_cosmos_crisis_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_crisis_module_v1_module_proto_rawDescData) + }) + return file_cosmos_crisis_module_v1_module_proto_rawDescData +} + +var file_cosmos_crisis_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_cosmos_crisis_module_v1_module_proto_goTypes = []interface{}{ + (*Module)(nil), // 0: cosmos.crisis.module.v1.Module +} +var file_cosmos_crisis_module_v1_module_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_cosmos_crisis_module_v1_module_proto_init() } +func file_cosmos_crisis_module_v1_module_proto_init() { + if File_cosmos_crisis_module_v1_module_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_cosmos_crisis_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); 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_crisis_module_v1_module_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_cosmos_crisis_module_v1_module_proto_goTypes, + DependencyIndexes: file_cosmos_crisis_module_v1_module_proto_depIdxs, + MessageInfos: file_cosmos_crisis_module_v1_module_proto_msgTypes, + }.Build() + File_cosmos_crisis_module_v1_module_proto = out.File + file_cosmos_crisis_module_v1_module_proto_rawDesc = nil + file_cosmos_crisis_module_v1_module_proto_goTypes = nil + file_cosmos_crisis_module_v1_module_proto_depIdxs = nil +} diff --git a/api/cosmos/distribution/module/v1/module.pulsar.go b/api/cosmos/distribution/module/v1/module.pulsar.go index 220523bdeb1..ee654b19c04 100644 --- a/api/cosmos/distribution/module/v1/module.pulsar.go +++ b/api/cosmos/distribution/module/v1/module.pulsar.go @@ -14,12 +14,14 @@ import ( ) var ( - md_Module protoreflect.MessageDescriptor + md_Module protoreflect.MessageDescriptor + fd_Module_fee_collector_name protoreflect.FieldDescriptor ) func init() { file_cosmos_distribution_module_v1_module_proto_init() md_Module = File_cosmos_distribution_module_v1_module_proto.Messages().ByName("Module") + fd_Module_fee_collector_name = md_Module.Fields().ByName("fee_collector_name") } var _ protoreflect.Message = (*fastReflection_Module)(nil) @@ -87,6 +89,12 @@ func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.FeeCollectorName != "" { + value := protoreflect.ValueOfString(x.FeeCollectorName) + if !f(fd_Module_fee_collector_name, value) { + return + } + } } // Has reports whether a field is populated. @@ -102,6 +110,8 @@ func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, proto // a repeated field is populated if it is non-empty. func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + return x.FeeCollectorName != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -118,6 +128,8 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + x.FeeCollectorName = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -134,6 +146,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + value := x.FeeCollectorName + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -154,6 +169,8 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + x.FeeCollectorName = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -174,6 +191,8 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + panic(fmt.Errorf("field fee_collector_name of message cosmos.distribution.module.v1.Module is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -187,6 +206,8 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.distribution.module.v1.Module.fee_collector_name": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.distribution.module.v1.Module")) @@ -256,6 +277,10 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { var n int var l int _ = l + l = len(x.FeeCollectorName) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -285,6 +310,13 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.FeeCollectorName) > 0 { + i -= len(x.FeeCollectorName) + copy(dAtA[i:], x.FeeCollectorName) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.FeeCollectorName))) + i-- + dAtA[i] = 0xa + } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) } else { @@ -334,6 +366,38 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: 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 FeeCollectorName", 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.FeeCollectorName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -387,6 +451,8 @@ type Module struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + FeeCollectorName string `protobuf:"bytes,1,opt,name=fee_collector_name,json=feeCollectorName,proto3" json:"fee_collector_name,omitempty"` } func (x *Module) Reset() { @@ -409,6 +475,13 @@ func (*Module) Descriptor() ([]byte, []int) { return file_cosmos_distribution_module_v1_module_proto_rawDescGZIP(), []int{0} } +func (x *Module) GetFeeCollectorName() string { + if x != nil { + return x.FeeCollectorName + } + return "" +} + var File_cosmos_distribution_module_v1_module_proto protoreflect.FileDescriptor var file_cosmos_distribution_module_v1_module_proto_rawDesc = []byte{ @@ -418,28 +491,31 @@ var file_cosmos_distribution_module_v1_module_proto_rawDesc = []byte{ 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, - 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x33, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x2d, 0x0a, - 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, - 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x80, 0x02, 0x0a, - 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, - 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x37, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, - 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x44, 0x4d, - 0xaa, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x29, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6b, 0x0a, + 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, 0x65, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x65, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x33, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x2d, 0x0a, 0x2b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, 0x64, 0x69, + 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x80, 0x02, 0x0a, 0x21, 0x63, + 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x37, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x44, 0x4d, 0xaa, 0x02, + 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x29, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/cosmos/mint/module/v1/module.pulsar.go b/api/cosmos/mint/module/v1/module.pulsar.go index f67f74cdc9b..fd88c28c9a1 100644 --- a/api/cosmos/mint/module/v1/module.pulsar.go +++ b/api/cosmos/mint/module/v1/module.pulsar.go @@ -14,12 +14,14 @@ import ( ) var ( - md_Module protoreflect.MessageDescriptor + md_Module protoreflect.MessageDescriptor + fd_Module_fee_collector_name protoreflect.FieldDescriptor ) func init() { file_cosmos_mint_module_v1_module_proto_init() md_Module = File_cosmos_mint_module_v1_module_proto.Messages().ByName("Module") + fd_Module_fee_collector_name = md_Module.Fields().ByName("fee_collector_name") } var _ protoreflect.Message = (*fastReflection_Module)(nil) @@ -87,6 +89,12 @@ func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.FeeCollectorName != "" { + value := protoreflect.ValueOfString(x.FeeCollectorName) + if !f(fd_Module_fee_collector_name, value) { + return + } + } } // Has reports whether a field is populated. @@ -102,6 +110,8 @@ func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, proto // a repeated field is populated if it is non-empty. func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + return x.FeeCollectorName != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -118,6 +128,8 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + x.FeeCollectorName = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -134,6 +146,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + value := x.FeeCollectorName + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -154,6 +169,8 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + x.FeeCollectorName = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -174,6 +191,8 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + panic(fmt.Errorf("field fee_collector_name of message cosmos.mint.module.v1.Module is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -187,6 +206,8 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.mint.module.v1.Module.fee_collector_name": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.module.v1.Module")) @@ -256,6 +277,10 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { var n int var l int _ = l + l = len(x.FeeCollectorName) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -285,6 +310,13 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.FeeCollectorName) > 0 { + i -= len(x.FeeCollectorName) + copy(dAtA[i:], x.FeeCollectorName) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.FeeCollectorName))) + i-- + dAtA[i] = 0xa + } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) } else { @@ -334,6 +366,38 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: 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 FeeCollectorName", 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.FeeCollectorName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -387,6 +451,8 @@ type Module struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + FeeCollectorName string `protobuf:"bytes,1,opt,name=fee_collector_name,json=feeCollectorName,proto3" json:"fee_collector_name,omitempty"` } func (x *Module) Reset() { @@ -409,6 +475,13 @@ func (*Module) Descriptor() ([]byte, []int) { return file_cosmos_mint_module_v1_module_proto_rawDescGZIP(), []int{0} } +func (x *Module) GetFeeCollectorName() string { + if x != nil { + return x.FeeCollectorName + } + return "" +} + var File_cosmos_mint_module_v1_module_proto protoreflect.FileDescriptor var file_cosmos_mint_module_v1_module_proto_rawDesc = []byte{ @@ -417,24 +490,27 @@ var file_cosmos_mint_module_v1_module_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, - 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x2b, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x25, 0x0a, - 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, - 0x6d, 0x69, 0x6e, 0x74, 0x42, 0xd0, 0x01, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, - 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 0x2f, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x4d, 0x4d, 0xaa, 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x4d, 0x69, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x4d, 0x69, 0x6e, 0x74, 0x5c, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x21, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x5c, 0x4d, 0x69, 0x6e, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x4d, 0x69, 0x6e, 0x74, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a, + 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, 0x65, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x65, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x2b, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x25, 0x0a, 0x23, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, 0x6d, 0x69, + 0x6e, 0x74, 0x42, 0xd0, 0x01, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x6d, 0x69, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, + 0xa2, 0x02, 0x03, 0x43, 0x4d, 0x4d, 0xaa, 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x4d, 0x69, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x4d, 0x69, 0x6e, 0x74, 0x5c, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x21, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, + 0x4d, 0x69, 0x6e, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x4d, 0x69, 0x6e, 0x74, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/baseapp/block_gas_test.go b/baseapp/block_gas_test.go index 9fd64fe46dd..747bda83f22 100644 --- a/baseapp/block_gas_test.go +++ b/baseapp/block_gas_test.go @@ -64,7 +64,7 @@ func TestBaseApp_BlockGas(t *testing.T) { } encCfg := simapp.MakeTestEncodingConfig() - app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, 0, encCfg, simtestutil.EmptyAppOptions{}, routerOpt) + app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, encCfg, simtestutil.EmptyAppOptions{}, routerOpt) app.InterfaceRegistry().RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}, ) diff --git a/depinject/README.md b/depinject/README.md index f4dab01bbcb..0aa0cbd317c 100644 --- a/depinject/README.md +++ b/depinject/README.md @@ -52,18 +52,13 @@ func NewSimApp( db dbm.DB, traceStore io.Writer, loadLatest bool, - invCheckPeriod uint, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *SimApp { - app := &SimApp{ - invCheckPeriod: invCheckPeriod, - } - var ( + app = &SimApp{} appBuilder *runtime.AppBuilder - msgServiceRouter *baseapp.MsgServiceRouter ) err := depinject.Inject(AppConfig, @@ -77,7 +72,6 @@ func NewSimApp( &app.BankKeeper, &app.FeeGrantKeeper, &app.StakingKeeper, - &msgServiceRouter, ) if err != nil { panic(err) diff --git a/docs/architecture/adr-038-state-listening.md b/docs/architecture/adr-038-state-listening.md index db3c2b8ea74..3c718cf206a 100644 --- a/docs/architecture/adr-038-state-listening.md +++ b/docs/architecture/adr-038-state-listening.md @@ -435,8 +435,7 @@ e.g. in `NewSimApp`: ```go func NewSimApp( - logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, invCheckPeriod uint, - encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), + logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *SimApp { ... diff --git a/proto/cosmos/crisis/module/v1/module.proto b/proto/cosmos/crisis/module/v1/module.proto new file mode 100644 index 00000000000..00670c18e51 --- /dev/null +++ b/proto/cosmos/crisis/module/v1/module.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package cosmos.crisis.module.v1; + +import "cosmos/app/v1alpha1/module.proto"; + +// Module is the config object of the crisis module. +message Module { + option (cosmos.app.v1alpha1.module) = { + go_import: "github.com/cosmos/cosmos-sdk/x/crisis" + }; + + string fee_collector_name = 1; +} \ No newline at end of file diff --git a/proto/cosmos/distribution/module/v1/module.proto b/proto/cosmos/distribution/module/v1/module.proto index a732ef61fdb..9eda82e11f1 100644 --- a/proto/cosmos/distribution/module/v1/module.proto +++ b/proto/cosmos/distribution/module/v1/module.proto @@ -9,4 +9,6 @@ message Module { option (cosmos.app.v1alpha1.module) = { go_import: "github.com/cosmos/cosmos-sdk/x/distribution" }; + + string fee_collector_name = 1; } \ No newline at end of file diff --git a/proto/cosmos/mint/module/v1/module.proto b/proto/cosmos/mint/module/v1/module.proto index 2e6393c596f..9922dc0dff1 100644 --- a/proto/cosmos/mint/module/v1/module.proto +++ b/proto/cosmos/mint/module/v1/module.proto @@ -9,4 +9,6 @@ message Module { option (cosmos.app.v1alpha1.module) = { go_import: "github.com/cosmos/cosmos-sdk/x/mint" }; + + string fee_collector_name = 1; } \ No newline at end of file diff --git a/server/README.md b/server/README.md index cc4b910631a..36833100b72 100644 --- a/server/README.md +++ b/server/README.md @@ -88,7 +88,6 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts server.A return simapp.NewSimApp( logger, db, traceStore, true, - cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), diff --git a/server/export_test.go b/server/export_test.go index 7f8a5f5e582..be92d72d417 100644 --- a/server/export_test.go +++ b/server/export_test.go @@ -129,7 +129,7 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t logger, _ := log.NewDefaultLogger("plain", "info", false) db := dbm.NewMemDB() encCfg := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(logger, db, nil, true, 0, encCfg, simtestutil.NewAppOptionsWithFlagHome(tempDir)) + app := simapp.NewSimApp(logger, db, nil, true, encCfg, simtestutil.NewAppOptionsWithFlagHome(tempDir)) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") @@ -160,13 +160,13 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t var simApp *simapp.SimApp if height != -1 { - simApp = simapp.NewSimApp(logger, db, nil, false, 0, encCfg, appOptions) + simApp = simapp.NewSimApp(logger, db, nil, false, encCfg, appOptions) if err := simApp.LoadHeight(height); err != nil { return types.ExportedApp{}, err } } else { - simApp = simapp.NewSimApp(logger, db, nil, true, 0, encCfg, appOptions) + simApp = simapp.NewSimApp(logger, db, nil, true, encCfg, appOptions) } return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/simapp/app.go b/simapp/app.go index b882ec52a98..9521e44f004 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -9,7 +9,6 @@ import ( "github.com/gorilla/mux" "github.com/rakyll/statik/fs" - "github.com/spf13/cast" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -166,7 +165,7 @@ type SimApp struct { MintKeeper mintkeeper.Keeper DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper - CrisisKeeper crisiskeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper AuthzKeeper authzkeeper.Keeper @@ -190,12 +189,13 @@ func init() { // NewSimApp returns a reference to an initialized SimApp. func NewSimApp( - logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, invCheckPeriod uint, encodingConfig simappparams.EncodingConfig, + logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *SimApp { var ( + app = &SimApp{} appBuilder *runtime.AppBuilder - app = &SimApp{invCheckPeriod: invCheckPeriod} + // merge the app.yaml and the appOpts in one config appConfig = depinject.Configs(AppConfig, depinject.Supply(appOpts)) ) @@ -219,6 +219,7 @@ func NewSimApp( &app.EvidenceKeeper, &app.DistrKeeper, &app.UpgradeKeeper, + &app.CrisisKeeper, ); err != nil { panic(err) } @@ -235,10 +236,6 @@ func NewSimApp( initParamsKeeper(app.ParamsKeeper) - app.CrisisKeeper = crisiskeeper.NewKeeper( - app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, - ) - // register the proposal types govRouter := govv1beta1.NewRouter() govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). @@ -266,14 +263,9 @@ func NewSimApp( // Sets the version setter for the upgrade module app.UpgradeKeeper.SetVersionSetter(app.BaseApp) - // NOTE: we may consider parsing `appOpts` inside module constructors. For the moment - // we prefer to be more strict in what arguments the modules expect. - skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)) - // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. if err := app.RegisterModules( - crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), gov.NewAppModule(app.appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), ); err != nil { panic(err) @@ -298,7 +290,7 @@ func NewSimApp( // Uncomment if you want to set a custom migration order here. // app.ModuleManager.SetOrderMigrations(custom order) - app.ModuleManager.RegisterInvariants(&app.CrisisKeeper) + app.ModuleManager.RegisterInvariants(app.CrisisKeeper) app.ModuleManager.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) // RegisterUpgradeHandlers is used for registering any on-chain upgrades. @@ -431,5 +423,4 @@ func GetMaccPerms() map[string][]string { // initParamsKeeper init params keeper and its subspaces func initParamsKeeper(paramsKeeper paramskeeper.Keeper) { paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable()) - paramsKeeper.Subspace(crisistypes.ModuleName) } diff --git a/simapp/app_config.go b/simapp/app_config.go index 504dd84a525..89b15158b52 100644 --- a/simapp/app_config.go +++ b/simapp/app_config.go @@ -31,6 +31,7 @@ import ( authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1" bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1" capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1" + crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1" distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1" evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1" feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1" @@ -190,6 +191,10 @@ var AppConfig = appconfig.Compose(&appv1alpha1.Config{ Name: feegrant.ModuleName, Config: appconfig.WrapAny(&feegrantmodulev1.Module{}), }, + { + Name: crisistypes.ModuleName, + Config: appconfig.WrapAny(&crisismodulev1.Module{}), + }, }, }) diff --git a/simapp/app_test.go b/simapp/app_test.go index b3e3874a2df..49076b2a1bf 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -41,11 +41,10 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { db := dbm.NewMemDB() logger, _ := log.NewDefaultLogger("plain", "info", false) app := NewSimappWithCustomOptions(t, false, SetupOptions{ - Logger: logger, - DB: db, - InvCheckPeriod: 0, - EncConfig: encCfg, - AppOpts: simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), + Logger: logger, + DB: db, + EncConfig: encCfg, + AppOpts: simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), }) for acc := range maccPerms { @@ -60,7 +59,7 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { logger2, _ := log.NewDefaultLogger("plain", "info", false) // Making a new app object with the db, so that initchain hasn't been called - app2 := NewSimApp(logger2, db, nil, true, 0, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) + app2 := NewSimApp(logger2, db, nil, true, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) _, err := app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -74,7 +73,7 @@ func TestRunMigrations(t *testing.T) { db := dbm.NewMemDB() encCfg := MakeTestEncodingConfig() logger, _ := log.NewDefaultLogger("plain", "info", false) - app := NewSimApp(logger, db, nil, true, 0, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) + app := NewSimApp(logger, db, nil, true, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) // Create a new baseapp and configurator for the purpose of this test. bApp := baseapp.NewBaseApp(app.Name(), logger, db, encCfg.TxConfig.TxDecoder()) @@ -207,7 +206,7 @@ func TestInitGenesisOnMigration(t *testing.T) { db := dbm.NewMemDB() encCfg := MakeTestEncodingConfig() logger, _ := log.NewDefaultLogger("plain", "info", false) - app := NewSimApp(logger, db, nil, true, 0, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) + app := NewSimApp(logger, db, nil, true, encCfg, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) // Create a mock module. This module will serve as the new module we're @@ -252,11 +251,10 @@ func TestUpgradeStateOnGenesis(t *testing.T) { db := dbm.NewMemDB() logger, _ := log.NewDefaultLogger("plain", "info", false) app := NewSimappWithCustomOptions(t, false, SetupOptions{ - Logger: logger, - DB: db, - InvCheckPeriod: 0, - EncConfig: encCfg, - AppOpts: simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), + Logger: logger, + DB: db, + EncConfig: encCfg, + AppOpts: simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), }) // make sure the upgrade keeper has version map in state diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index 9536a9699d1..115dd62b607 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" @@ -31,7 +33,11 @@ func BenchmarkFullAppSimulation(b *testing.B) { require.NoError(b, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), interBlockCacheOpt()) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -78,7 +84,11 @@ func BenchmarkInvariants(b *testing.B) { require.NoError(b, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), interBlockCacheOpt()) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/simapp/sim_test.go b/simapp/sim_test.go index d50a6b0df4d..fc7bc7e8c0b 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -15,6 +15,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -71,7 +73,11 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), fauxMerkleModeOpt) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // run randomized simulation @@ -109,7 +115,11 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), fauxMerkleModeOpt) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -149,7 +159,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, MakeTestEncodingConfig(), appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) var genesisState GenesisState @@ -218,7 +228,11 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), fauxMerkleModeOpt) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -263,7 +277,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, MakeTestEncodingConfig(), appOptions, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -302,6 +316,10 @@ func TestAppStateDeterminism(t *testing.T) { numTimesToRunPerSeed := 5 appHashList := make([]json.RawMessage, numTimesToRunPerSeed) + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue + for i := 0; i < numSeeds; i++ { config.Seed = rand.Int63() @@ -314,7 +332,7 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - app := NewSimApp(logger, db, nil, true, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome), interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, MakeTestEncodingConfig(), appOptions, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index af91a043777..b1747abdcea 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cast" "github.com/spf13/cobra" + "github.com/spf13/viper" tmcfg "github.com/tendermint/tendermint/config" tmcli "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" @@ -278,7 +279,6 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a return simapp.NewSimApp( logger, db, traceStore, true, - cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), a.encCfg, appOpts, baseapp.SetPruning(pruningOpts), @@ -307,14 +307,23 @@ func (a appCreator) appExport( return servertypes.ExportedApp{}, errors.New("application home not set") } + viperAppOpts, ok := appOpts.(*viper.Viper) + if !ok { + return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper") + } + + // overwrite the FlagInvCheckPeriod + viperAppOpts.Set(server.FlagInvCheckPeriod, 1) + appOpts = viperAppOpts + if height != -1 { - simApp = simapp.NewSimApp(logger, db, traceStore, false, uint(1), a.encCfg, appOpts) + simApp = simapp.NewSimApp(logger, db, traceStore, false, a.encCfg, appOpts) if err := simApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - simApp = simapp.NewSimApp(logger, db, traceStore, true, uint(1), a.encCfg, appOpts) + simApp = simapp.NewSimApp(logger, db, traceStore, true, a.encCfg, appOpts) } return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 84ab354dd1a..fd6426c91d4 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -18,9 +18,11 @@ import ( "cosmossdk.io/math" bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/depinject" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/testutil/mock" @@ -34,17 +36,21 @@ import ( // SetupOptions defines arguments that are passed into `Simapp` constructor. type SetupOptions struct { - Logger log.Logger - DB *dbm.MemDB - InvCheckPeriod uint - EncConfig params.EncodingConfig - AppOpts types.AppOptions + Logger log.Logger + DB *dbm.MemDB + EncConfig params.EncodingConfig + AppOpts types.AppOptions } func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) { db := dbm.NewMemDB() encCdc := MakeTestEncodingConfig() - app := NewSimApp(log.NewNopLogger(), db, nil, true, invCheckPeriod, encCdc, simtestutil.NewAppOptionsWithFlagHome(DefaultNodeHome)) + + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = invCheckPeriod + + app := NewSimApp(log.NewNopLogger(), db, nil, true, encCdc, appOptions) if withGenesis { return app, NewDefaultGenesisState(encCdc.Codec) } @@ -70,7 +76,7 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), } - app := NewSimApp(options.Logger, options.DB, nil, true, options.InvCheckPeriod, options.EncConfig, options.AppOpts) + app := NewSimApp(options.Logger, options.DB, nil, true, options.EncConfig, options.AppOpts) genesisState := NewDefaultGenesisState(app.appCodec) genesisState, err = simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) require.NoError(t, err) diff --git a/testutil/network/network.go b/testutil/network/network.go index bc39a4118b8..19f2b0fc66c 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -63,7 +63,7 @@ type AppConstructor = func(val Validator) servertypes.Application func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { return func(val Validator) servertypes.Application { return simapp.NewSimApp( - val.Ctx.Logger, dbm.NewMemDB(), nil, true, 0, + val.Ctx.Logger, dbm.NewMemDB(), nil, true, encodingCfg, simtestutil.NewAppOptionsWithFlagHome(val.Ctx.Config.RootDir), baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go index 07362c01b6d..8c6d29a0438 100644 --- a/testutil/sims/app_helpers.go +++ b/testutil/sims/app_helpers.go @@ -245,7 +245,12 @@ func (ao EmptyAppOptions) Get(o string) interface{} { type AppOptionsMap map[string]interface{} func (m AppOptionsMap) Get(key string) interface{} { - return m[key] + v, ok := m[key] + if !ok { + return interface{}(nil) + } + + return v } func NewAppOptionsWithFlagHome(homePath string) servertypes.AppOptions { diff --git a/x/auth/tx/module/module.go b/x/auth/tx/module/module.go index 1128b2afa81..a4850bfc9ae 100644 --- a/x/auth/tx/module/module.go +++ b/x/auth/tx/module/module.go @@ -30,9 +30,9 @@ type txInputs struct { Config *modulev1.Module ProtoCodecMarshaler codec.ProtoCodecMarshaler - AccountKeeper ante.AccountKeeper `key:"cosmos.auth.v1.AccountKeeper" optional:"true"` - BankKeeper authtypes.BankKeeper `key:"cosmos.bank.v1.Keeper" optional:"true"` - FeeGrantKeeper feegrantkeeper.Keeper `key:"cosmos.feegrant.v1.Keeper" optional:"true"` + AccountKeeper ante.AccountKeeper `optional:"true"` + BankKeeper authtypes.BankKeeper `optional:"true"` + FeeGrantKeeper feegrantkeeper.Keeper `optional:"true"` } type txOutputs struct { diff --git a/x/crisis/keeper/genesis.go b/x/crisis/keeper/genesis.go index 8420201d4e9..f8553bbbd55 100644 --- a/x/crisis/keeper/genesis.go +++ b/x/crisis/keeper/genesis.go @@ -6,12 +6,12 @@ import ( ) // new crisis genesis -func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) { +func (k *Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) { k.SetConstantFee(ctx, data.ConstantFee) } // ExportGenesis returns a GenesisState for a given context and keeper. -func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { +func (k *Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { constantFee := k.GetConstantFee(ctx) return types.NewGenesisState(constantFee) } diff --git a/x/crisis/keeper/keeper.go b/x/crisis/keeper/keeper.go index 8dcf447c60e..b1442ff5d46 100644 --- a/x/crisis/keeper/keeper.go +++ b/x/crisis/keeper/keeper.go @@ -26,13 +26,13 @@ type Keeper struct { func NewKeeper( paramSpace paramtypes.Subspace, invCheckPeriod uint, supplyKeeper types.SupplyKeeper, feeCollectorName string, -) Keeper { +) *Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) } - return Keeper{ + return &Keeper{ routes: make([]types.InvarRoute, 0), paramSpace: paramSpace, invCheckPeriod: invCheckPeriod, @@ -42,7 +42,7 @@ func NewKeeper( } // Logger returns a module-specific logger. -func (k Keeper) Logger(ctx sdk.Context) log.Logger { +func (k *Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } @@ -53,12 +53,12 @@ func (k *Keeper) RegisterRoute(moduleName, route string, invar sdk.Invariant) { } // Routes - return the keeper's invariant routes -func (k Keeper) Routes() []types.InvarRoute { +func (k *Keeper) Routes() []types.InvarRoute { return k.routes } // Invariants returns a copy of all registered Crisis keeper invariants. -func (k Keeper) Invariants() []sdk.Invariant { +func (k *Keeper) Invariants() []sdk.Invariant { invars := make([]sdk.Invariant, len(k.routes)) for i, route := range k.routes { invars[i] = route.Invar @@ -68,7 +68,7 @@ func (k Keeper) Invariants() []sdk.Invariant { // AssertInvariants asserts all registered invariants. If any invariant fails, // the method panics. -func (k Keeper) AssertInvariants(ctx sdk.Context) { +func (k *Keeper) AssertInvariants(ctx sdk.Context) { logger := k.Logger(ctx) start := time.Now() @@ -90,9 +90,9 @@ func (k Keeper) AssertInvariants(ctx sdk.Context) { } // InvCheckPeriod returns the invariant checks period. -func (k Keeper) InvCheckPeriod() uint { return k.invCheckPeriod } +func (k *Keeper) InvCheckPeriod() uint { return k.invCheckPeriod } // SendCoinsFromAccountToFeeCollector transfers amt to the fee collector account. -func (k Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) error { +func (k *Keeper) SendCoinsFromAccountToFeeCollector(ctx sdk.Context, senderAddr sdk.AccAddress, amt sdk.Coins) error { return k.supplyKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, k.feeCollectorName, amt) } diff --git a/x/crisis/keeper/msg_server.go b/x/crisis/keeper/msg_server.go index a3eb07e6ba4..7e02a370e90 100644 --- a/x/crisis/keeper/msg_server.go +++ b/x/crisis/keeper/msg_server.go @@ -7,9 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/crisis/types" ) -var _ types.MsgServer = Keeper{} +var _ types.MsgServer = &Keeper{} -func (k Keeper) VerifyInvariant(goCtx context.Context, msg *types.MsgVerifyInvariant) (*types.MsgVerifyInvariantResponse, error) { +func (k *Keeper) VerifyInvariant(goCtx context.Context, msg *types.MsgVerifyInvariant) (*types.MsgVerifyInvariantResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) constantFee := sdk.NewCoins(k.GetConstantFee(ctx)) diff --git a/x/crisis/keeper/params.go b/x/crisis/keeper/params.go index d44efa4ebf1..82a42a30896 100644 --- a/x/crisis/keeper/params.go +++ b/x/crisis/keeper/params.go @@ -6,12 +6,12 @@ import ( ) // GetConstantFee get's the constant fee from the paramSpace -func (k Keeper) GetConstantFee(ctx sdk.Context) (constantFee sdk.Coin) { +func (k *Keeper) GetConstantFee(ctx sdk.Context) (constantFee sdk.Coin) { k.paramSpace.Get(ctx, types.ParamStoreKeyConstantFee, &constantFee) return } // GetConstantFee set's the constant fee in the paramSpace -func (k Keeper) SetConstantFee(ctx sdk.Context, constantFee sdk.Coin) { +func (k *Keeper) SetConstantFee(ctx sdk.Context, constantFee sdk.Coin) { k.paramSpace.Set(ctx, types.ParamStoreKeyConstantFee, constantFee) } diff --git a/x/crisis/module.go b/x/crisis/module.go index 7c058a4f22e..8afbf8d89c0 100644 --- a/x/crisis/module.go +++ b/x/crisis/module.go @@ -5,19 +5,28 @@ import ( "fmt" "time" - "github.com/grpc-ecosystem/grpc-gateway/runtime" + "cosmossdk.io/core/appmodule" + gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cast" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" + modulev1 "cosmossdk.io/api/cosmos/crisis/module/v1" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/depinject" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/server" + servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis/client/cli" "github.com/cosmos/cosmos-sdk/x/crisis/keeper" "github.com/cosmos/cosmos-sdk/x/crisis/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" ) var ( @@ -60,7 +69,7 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the capability module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} +func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *gwruntime.ServeMux) {} // GetTxCmd returns the root tx command for the crisis module. func (b AppModuleBasic) GetTxCmd() *cobra.Command { @@ -164,3 +173,54 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val EndBlocker(ctx, *am.keeper) return []abci.ValidatorUpdate{} } + +// New App Wiring Setup + +func init() { + appmodule.Register( + &modulev1.Module{}, + appmodule.Provide(provideModuleBasic, provideModule), + ) +} + +type crisisInputs struct { + depinject.In + + Config *modulev1.Module + AppOpts servertypes.AppOptions `optional:"true"` + Subspace paramstypes.Subspace + BankKeeper types.SupplyKeeper +} + +type crisisOutputs struct { + depinject.Out + + Module runtime.AppModuleWrapper + CrisisKeeper *keeper.Keeper +} + +func provideModuleBasic() runtime.AppModuleBasicWrapper { + return runtime.WrapAppModuleBasic(AppModuleBasic{}) +} + +func provideModule(in crisisInputs) crisisOutputs { + invalidCheckPeriod := cast.ToUint(in.AppOpts.Get(server.FlagInvCheckPeriod)) + + feeCollectorName := in.Config.FeeCollectorName + if feeCollectorName == "" { + feeCollectorName = authtypes.FeeCollectorName + } + + k := keeper.NewKeeper( + in.Subspace, + invalidCheckPeriod, + in.BankKeeper, + feeCollectorName, + ) + + skipGenesisInvariants := cast.ToBool(in.AppOpts.Get(FlagSkipGenesisInvariants)) + + m := NewAppModule(k, skipGenesisInvariants) + + return crisisOutputs{CrisisKeeper: k, Module: runtime.WrapAppModule(m)} +} diff --git a/x/distribution/module.go b/x/distribution/module.go index 24c783f3b22..532d7e61580 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -225,6 +225,7 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper { type distrInputs struct { depinject.In + Config *modulev1.Module Key *store.KVStoreKey Cdc codec.Codec Subspace paramstypes.Subspace @@ -243,7 +244,12 @@ type distrOutputs struct { } func provideModule(in distrInputs) distrOutputs { - k := keeper.NewKeeper(in.Cdc, in.Key, in.Subspace, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, authtypes.FeeCollectorName) + feeCollectorName := in.Config.FeeCollectorName + if feeCollectorName == "" { + feeCollectorName = authtypes.FeeCollectorName + } + + k := keeper.NewKeeper(in.Cdc, in.Key, in.Subspace, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, feeCollectorName) m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper) return distrOutputs{ diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index 82f8e9c4aac..518ad8d8a9f 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -74,7 +74,7 @@ func TestImportExportQueues(t *testing.T) { } db := dbm.NewMemDB() - app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, 0, simapp.MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(simapp.DefaultNodeHome)) + app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.MakeTestEncodingConfig(), simtestutil.NewAppOptionsWithFlagHome(simapp.DefaultNodeHome)) app2.InitChain( abci.RequestInitChain{ diff --git a/x/gov/module_test.go b/x/gov/module_test.go index 761cd712878..f9c7c97137b 100644 --- a/x/gov/module_test.go +++ b/x/gov/module_test.go @@ -10,6 +10,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/simapp" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -19,7 +21,12 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, 5, encCdc, simtestutil.NewAppOptionsWithFlagHome(simapp.DefaultNodeHome)) + + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = simapp.DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = 5 + + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, encCdc, appOptions) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/mint/module.go b/x/mint/module.go index a574f921eab..c802a163090 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -238,8 +238,9 @@ func provideModuleBasic() runtime.AppModuleBasicWrapper { type mintInputs struct { depinject.In - Key *store.KVStoreKey - Cdc codec.Codec + Config *modulev1.Module + Key *store.KVStoreKey + Cdc codec.Codec // LegacySubspace is used solely for migration of x/params managed parameters LegacySubspace exported.Subspace @@ -257,15 +258,22 @@ type mintOutputs struct { } func provideModule(in mintInputs) mintOutputs { + feeCollectorName := in.Config.FeeCollectorName + if feeCollectorName == "" { + feeCollectorName = authtypes.FeeCollectorName + } + k := keeper.NewKeeper( in.Cdc, in.Key, in.StakingKeeper, in.AccountKeeper, in.BankKeeper, - authtypes.FeeCollectorName, + feeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + + // TODO: allow to set inflation calculation function m := NewAppModule(in.Cdc, k, in.AccountKeeper, nil, in.LegacySubspace) return mintOutputs{MintKeeper: k, Module: runtime.WrapAppModule(m)} diff --git a/x/slashing/module.go b/x/slashing/module.go index bdec7d7054c..321cdba94cc 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -195,9 +195,9 @@ type slashingInputs struct { Key *store.KVStoreKey Cdc codec.Codec - AccountKeeper types.AccountKeeper `key:"cosmos.auth.v1.AccountKeeper"` - BankKeeper types.BankKeeper `key:"cosmos.bank.v1.Keeper"` - StakingKeeper types.StakingKeeper `key:"cosmos.staking.v1.Keeper"` + AccountKeeper types.AccountKeeper + BankKeeper types.BankKeeper + StakingKeeper types.StakingKeeper Subspace paramstypes.Subspace } diff --git a/x/staking/module_test.go b/x/staking/module_test.go index 5fe1d917f4f..12faab19e0c 100644 --- a/x/staking/module_test.go +++ b/x/staking/module_test.go @@ -10,6 +10,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/simapp" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -19,7 +21,12 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, 5, encCdc, simtestutil.NewAppOptionsWithFlagHome(simapp.DefaultNodeHome)) + + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = simapp.DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = 5 + + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, encCdc, appOptions) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) From de279d0dc251d8b672b96de12b6ac6145ddab04d Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 17:51:56 +0100 Subject: [PATCH 19/21] updates --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f64659902e3..97144f905e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* (cli) [#12028](https://github.com/cosmos/cosmos-sdk/pull/12028) Add the `tendermint key-migrate` to perform Tendermint v0.35 DB key migration.12363 +* (cli) [#12028](https://github.com/cosmos/cosmos-sdk/pull/12028) Add the `tendermint key-migrate` to perform Tendermint v0.35 DB key migration. * (query) [#12253](https://github.com/cosmos/cosmos-sdk/pull/12253) Add `GenericFilteredPaginate` to the `query` package to improve UX. ### Improvements From 3ff1bfe2a0856617df02c0ce7d4d148310cdebdc Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 30 Jun 2022 22:06:08 +0100 Subject: [PATCH 20/21] updates --- x/mint/exported/exported.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/x/mint/exported/exported.go b/x/mint/exported/exported.go index 82ab53b591e..000114e6194 100644 --- a/x/mint/exported/exported.go +++ b/x/mint/exported/exported.go @@ -6,13 +6,7 @@ import ( ) type ( - // ParamSet defines an interface that implements the legacy x/params ParamSet - // type. - // - // NOTE: This is used solely for migration of x/params managed parameters. - ParamSet interface { - ParamSetPairs() paramtypes.ParamSetPairs - } + ParamSet = paramtypes.ParamSet // Subspace defines an interface that implements the legacy x/params Subspace // type. From b41cd38c89475e24aad36c1c28ea66bf0cbff3f3 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 1 Jul 2022 11:51:33 +0100 Subject: [PATCH 21/21] updates --- contrib/rosetta/rosetta-ci/data.tar.gz | Bin 44805 -> 45317 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/rosetta/rosetta-ci/data.tar.gz b/contrib/rosetta/rosetta-ci/data.tar.gz index f1d026ddcfad30abd96155f4f92e1bb4b6cb1c8e..6e09fd05186cc948b2f5d68f7bfd0a14e309c7e8 100644 GIT binary patch literal 45317 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[Mu$ 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%0AQn=C(Pb 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