diff --git a/api/cosmos/mint/v1beta1/mint.pulsar.go b/api/cosmos/mint/v1beta1/mint.pulsar.go index 8007c79c9630..2ad70c1ed755 100644 --- a/api/cosmos/mint/v1beta1/mint.pulsar.go +++ b/api/cosmos/mint/v1beta1/mint.pulsar.go @@ -507,6 +507,7 @@ var ( fd_Params_inflation_min protoreflect.FieldDescriptor fd_Params_goal_bonded protoreflect.FieldDescriptor fd_Params_blocks_per_year protoreflect.FieldDescriptor + fd_Params_max_supply protoreflect.FieldDescriptor ) func init() { @@ -518,6 +519,7 @@ func init() { fd_Params_inflation_min = md_Params.Fields().ByName("inflation_min") fd_Params_goal_bonded = md_Params.Fields().ByName("goal_bonded") fd_Params_blocks_per_year = md_Params.Fields().ByName("blocks_per_year") + fd_Params_max_supply = md_Params.Fields().ByName("max_supply") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -621,6 +623,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.MaxSupply != "" { + value := protoreflect.ValueOfString(x.MaxSupply) + if !f(fd_Params_max_supply, value) { + return + } + } } // Has reports whether a field is populated. @@ -648,6 +656,8 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { return x.GoalBonded != "" case "cosmos.mint.v1beta1.Params.blocks_per_year": return x.BlocksPerYear != uint64(0) + case "cosmos.mint.v1beta1.Params.max_supply": + return x.MaxSupply != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -676,6 +686,8 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { x.GoalBonded = "" case "cosmos.mint.v1beta1.Params.blocks_per_year": x.BlocksPerYear = uint64(0) + case "cosmos.mint.v1beta1.Params.max_supply": + x.MaxSupply = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -710,6 +722,9 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro case "cosmos.mint.v1beta1.Params.blocks_per_year": value := x.BlocksPerYear return protoreflect.ValueOfUint64(value) + case "cosmos.mint.v1beta1.Params.max_supply": + value := x.MaxSupply + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -742,6 +757,8 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto x.GoalBonded = value.Interface().(string) case "cosmos.mint.v1beta1.Params.blocks_per_year": x.BlocksPerYear = value.Uint() + case "cosmos.mint.v1beta1.Params.max_supply": + x.MaxSupply = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -774,6 +791,8 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore panic(fmt.Errorf("field goal_bonded of message cosmos.mint.v1beta1.Params is not mutable")) case "cosmos.mint.v1beta1.Params.blocks_per_year": panic(fmt.Errorf("field blocks_per_year of message cosmos.mint.v1beta1.Params is not mutable")) + case "cosmos.mint.v1beta1.Params.max_supply": + panic(fmt.Errorf("field max_supply of message cosmos.mint.v1beta1.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -799,6 +818,8 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor return protoreflect.ValueOfString("") case "cosmos.mint.v1beta1.Params.blocks_per_year": return protoreflect.ValueOfUint64(uint64(0)) + case "cosmos.mint.v1beta1.Params.max_supply": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.mint.v1beta1.Params")) @@ -891,6 +912,10 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { if x.BlocksPerYear != 0 { n += 1 + runtime.Sov(uint64(x.BlocksPerYear)) } + l = len(x.MaxSupply) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -920,6 +945,13 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.MaxSupply) > 0 { + i -= len(x.MaxSupply) + copy(dAtA[i:], x.MaxSupply) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.MaxSupply))) + i-- + dAtA[i] = 0x3a + } if x.BlocksPerYear != 0 { i = runtime.EncodeVarint(dAtA, i, uint64(x.BlocksPerYear)) i-- @@ -1188,6 +1220,38 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { break } } + case 7: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxSupply", 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.MaxSupply = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1300,6 +1364,8 @@ type Params struct { GoalBonded string `protobuf:"bytes,5,opt,name=goal_bonded,json=goalBonded,proto3" json:"goal_bonded,omitempty"` // expected blocks per year BlocksPerYear uint64 `protobuf:"varint,6,opt,name=blocks_per_year,json=blocksPerYear,proto3" json:"blocks_per_year,omitempty"` + // maximum supply for the token + MaxSupply string `protobuf:"bytes,7,opt,name=max_supply,json=maxSupply,proto3" json:"max_supply,omitempty"` } func (x *Params) Reset() { @@ -1364,6 +1430,13 @@ func (x *Params) GetBlocksPerYear() uint64 { return 0 } +func (x *Params) GetMaxSupply() string { + if x != nil { + return x.MaxSupply + } + return "" +} + var File_cosmos_mint_v1beta1_mint_proto protoreflect.FileDescriptor var file_cosmos_mint_v1beta1_mint_proto_rawDesc = []byte{ @@ -1386,7 +1459,7 @@ var file_cosmos_mint_v1beta1_mint_proto_rawDesc = []byte{ 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x10, 0x61, 0x6e, 0x6e, 0x75, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x03, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb9, 0x04, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x74, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x74, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x6a, 0x0a, 0x15, 0x69, 0x6e, 0x66, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, @@ -1415,22 +1488,26 @@ var file_cosmos_mint_v1beta1_mint_proto_rawDesc = []byte{ 0x2a, 0x01, 0x52, 0x0a, 0x67, 0x6f, 0x61, 0x6c, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x50, - 0x65, 0x72, 0x59, 0x65, 0x61, 0x72, 0x3a, 0x1d, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xc4, 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, 0x09, 0x4d, 0x69, 0x6e, 0x74, 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, + 0x65, 0x72, 0x59, 0x65, 0x61, 0x72, 0x12, 0x4a, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, + 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, + 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x53, 0x75, 0x70, 0x70, + 0x6c, 0x79, 0x3a, 0x1d, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, + 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x42, 0xc4, 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, 0x09, 0x4d, + 0x69, 0x6e, 0x74, 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 ( diff --git a/go.mod b/go.mod index 2fefb9784107..e35b51e58ce6 100644 --- a/go.mod +++ b/go.mod @@ -221,6 +221,7 @@ require ( // Below are the long-lived replace of the Cosmos SDK replace ( + cosmossdk.io/api => ./api // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 // dgrijalva/jwt-go is deprecated and doesn't receive security updates. diff --git a/go.sum b/go.sum index c44b05030d43..c5552f120325 100644 --- a/go.sum +++ b/go.sum @@ -614,8 +614,6 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -cosmossdk.io/api v1.0.0-rc.1 h1:KwZHIMveoeg6YVwvKZxJLp7be5uk6qmnqNAar2tPxVU= -cosmossdk.io/api v1.0.0-rc.1/go.mod h1:8YOT+XjVFb9eZJk62YqjFILOm8MlLhbnkC9/jxIYri8= cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= cosmossdk.io/core v1.1.0-rc.1 h1:VhF5xd4uJZt/lQzbl8qT1W3Pcrklp4RSnugcWQZyf5M= diff --git a/proto/cosmos/mint/v1beta1/mint.proto b/proto/cosmos/mint/v1beta1/mint.proto index 440a392dbd87..48dadabef6aa 100644 --- a/proto/cosmos/mint/v1beta1/mint.proto +++ b/proto/cosmos/mint/v1beta1/mint.proto @@ -59,4 +59,10 @@ message Params { ]; // expected blocks per year uint64 blocks_per_year = 6; + // maximum supply for the token + string max_supply = 7 [ + (cosmos_proto.scalar) = "cosmos.Int", + (gogoproto.customtype) = "cosmossdk.io/math.Int", + (gogoproto.nullable) = false + ]; } diff --git a/tests/e2e/mint/grpc.go b/tests/e2e/mint/grpc.go index fc513b5073cf..86d40cec9518 100644 --- a/tests/e2e/mint/grpc.go +++ b/tests/e2e/mint/grpc.go @@ -29,7 +29,7 @@ func (s *E2ETestSuite) TestQueryGRPC() { &minttypes.QueryParamsResponse{}, &minttypes.QueryParamsResponse{ Params: minttypes.NewParams("stake", math.LegacyNewDecWithPrec(13, 2), math.LegacyNewDecWithPrec(100, 2), - math.LegacyNewDec(1), math.LegacyNewDecWithPrec(67, 2), (60 * 60 * 8766 / 5)), + math.LegacyNewDec(1), math.LegacyNewDecWithPrec(67, 2), (60 * 60 * 8766 / 5), math.ZeroInt()), }, }, { diff --git a/tests/go.mod b/tests/go.mod index c357188a4731..7b07bad5f08f 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -219,6 +219,7 @@ require ( // Below are the long-lived replace for tests. replace ( + cosmossdk.io/api => ../api // We always want to test against the latest version of the simapp. cosmossdk.io/simapp => ../simapp github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 diff --git a/tools/benchmark/CHANGELOG.md b/tools/benchmark/CHANGELOG.md index cc9a54ef1ea4..94a28ba2ab21 100644 --- a/tools/benchmark/CHANGELOG.md +++ b/tools/benchmark/CHANGELOG.md @@ -28,3 +28,5 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [v0.2.0-rc.1](https://github.com/cosmos/cosmos-sdk/releases/tag/tools/benchmark/v0.2.0-rc.1) - 2024-12-18 * [#22778](https://github.com/cosmos/cosmos-sdk/pull/22778) - Initial commit +* [19896](https://github.com/cosmos/cosmos-sdk/pull/19896) Added a new max supply genesis param to existing params. + diff --git a/x/gov/types/config.go b/x/gov/types/config.go index b00d8fba2acf..3860687b54a6 100644 --- a/x/gov/types/config.go +++ b/x/gov/types/config.go @@ -1,6 +1,6 @@ package types -// Config is a config struct used for initialising the gov module to avoid using globals. +// Config is a config struct used for initializing the gov module to avoid using globals. type Config struct { // MaxMetadataLen defines the maximum proposal metadata length. MaxMetadataLen uint64 diff --git a/x/mint/README.md b/x/mint/README.md index 89dab770470e..8ab07bba0eaa 100644 --- a/x/mint/README.md +++ b/x/mint/README.md @@ -140,17 +140,21 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/mint/v1beta1/ The mint module stores its params in state with the prefix of `0x01`, it can be updated with governance or the address with authority. +**Note:** With the latest update, the addition of the `MaxSupply` parameter allows controlling the maximum supply of tokens minted by the module. +A value of `0` indicates an unlimited supply. * Params: `mint/params -> legacy_amino(params)` ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/mint/v1beta1/mint.proto#L26-L59 +https://github.com/cosmos/cosmos-sdk/blob/7068d0da52d954430054768b2c56aff44666933b/x/mint/proto/cosmos/mint/v1beta1/mint.proto#L26-L68 ``` ## Begin-Block Minting parameters are recalculated and inflation paid at the beginning of each block. +The minting logic in the `BeginBlocker` function provides an optional feature for controlling token minting based on the maximum allowable supply (MaxSupply). This feature allows users to adjust the minting process according to their specific requirements and use cases. However, it's important to note that the MaxSupply parameter is independent of the minting process and assumes that any adjustments to the total supply, including burning tokens, are handled by external modules. + ### Inflation rate calculation Inflation rate is calculated using an "inflation calculation function" that's @@ -213,15 +217,17 @@ BlockProvision(params Params) sdk.Coin { ## Parameters The minting module contains the following parameters: +Note: `0` indicates unlimited supply for MaxSupply param -| Key | Type | Example | -|---------------------|-----------------|------------------------| -| MintDenom | string | "uatom" | -| InflationRateChange | string (dec) | "0.130000000000000000" | -| InflationMax | string (dec) | "0.200000000000000000" | -| InflationMin | string (dec) | "0.070000000000000000" | -| GoalBonded | string (dec) | "0.670000000000000000" | -| BlocksPerYear | string (uint64) | "6311520" | +| Key | Type | Example | +|---------------------|------------------|------------------------| +| MintDenom | string | "uatom" | +| InflationRateChange | string (dec) | "0.130000000000000000" | +| InflationMax | string (dec) | "0.200000000000000000" | +| InflationMin | string (dec) | "0.070000000000000000" | +| GoalBonded | string (dec) | "0.670000000000000000" | +| BlocksPerYear | string (uint64) | "6311520" | +| MaxSupply | string (math.Int)| "0" | ## Events @@ -309,6 +315,7 @@ inflation_max: "0.200000000000000000" inflation_min: "0.070000000000000000" inflation_rate_change: "0.130000000000000000" mint_denom: stake +max_supply: "0" ``` ### gRPC @@ -383,7 +390,8 @@ Example Output: "inflationMax": "200000000000000000", "inflationMin": "70000000000000000", "goalBonded": "670000000000000000", - "blocksPerYear": "6311520" + "blocksPerYear": "6311520", + "maxSupply": "0", } } ``` @@ -454,7 +462,8 @@ Example Output: "inflationMax": "200000000000000000", "inflationMin": "70000000000000000", "goalBonded": "670000000000000000", - "blocksPerYear": "6311520" + "blocksPerYear": "6311520", + "maxSupply": "0", } } ``` diff --git a/x/mint/keeper/genesis_test.go b/x/mint/keeper/genesis_test.go index fe1d91edd36d..0c4818007e98 100644 --- a/x/mint/keeper/genesis_test.go +++ b/x/mint/keeper/genesis_test.go @@ -69,6 +69,7 @@ func (s *GenesisTestSuite) TestImportExportGenesis() { math.LegacyNewDecWithPrec(9, 2), math.LegacyNewDecWithPrec(69, 2), uint64(60*60*8766/5), + math.ZeroInt(), ) s.keeper.InitGenesis(s.sdkCtx, s.accountKeeper, genesisState) diff --git a/x/mint/keeper/migrator.go b/x/mint/keeper/migrator.go index 3e85e6edba08..80ed2dffa11c 100644 --- a/x/mint/keeper/migrator.go +++ b/x/mint/keeper/migrator.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mint/exported" v2 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v2" + v3 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v3" ) // Migrator is a struct for handling in-place state migrations. @@ -27,3 +28,9 @@ func NewMigrator(k Keeper, ss exported.Subspace) Migrator { func (m Migrator) Migrate1to2(ctx sdk.Context) error { return v2.Migrate(ctx, m.keeper.storeService.OpenKVStore(ctx), m.legacySubspace, m.keeper.cdc) } + +// Migrate2to3 migrates the x/mint module state from the consensus version 2 to +// version 3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + return v3.Migrate(ctx, m.keeper.storeService.OpenKVStore(ctx), m.keeper.cdc, m.keeper.Params) +} diff --git a/x/mint/keeper/mint.go b/x/mint/keeper/mint.go index f3ae7fb6df61..ed1700a9264e 100644 --- a/x/mint/keeper/mint.go +++ b/x/mint/keeper/mint.go @@ -40,19 +40,43 @@ func DefaultMintFn(ic types.InflationCalculationFn) MintFn { return err } + // update minter's inflation and annual provisions minter.Inflation = ic(ctx, minter, params, bondedRatio) minter.AnnualProvisions = minter.NextAnnualProvisions(params, totalStakingSupply) if err = k.Minter.Set(ctx, minter); err != nil { return err } - // mint coins, update supply + // calculate minted coins mintedCoin := minter.BlockProvision(params) mintedCoins := sdk.NewCoins(mintedCoin) - err = k.MintCoins(ctx, mintedCoins) - if err != nil { - return err + maxSupply := params.MaxSupply + totalSupply := k.bankKeeper.GetSupply(ctx, params.MintDenom).Amount // fetch total supply from the bank module + + // if maxSupply is not infinite, check against max_supply parameter + if !maxSupply.IsZero() { + if totalSupply.Add(mintedCoins.AmountOf(params.MintDenom)).GT(maxSupply) { + // calculate the difference between maxSupply and totalSupply + diff := maxSupply.Sub(totalSupply) + // mint the difference + diffCoin := sdk.NewCoin(params.MintDenom, diff) + diffCoins := sdk.NewCoins(diffCoin) + + // mint coins + if err := k.MintCoins(ctx, diffCoins); err != nil { + return err + } + mintedCoins = diffCoins + } + } + + // mint coins if maxSupply is infinite or total staking supply is less than maxSupply + if maxSupply.IsZero() || totalSupply.Add(mintedCoins.AmountOf(params.MintDenom)).LT(maxSupply) { + // mint coins + if err := k.MintCoins(ctx, mintedCoins); err != nil { + return err + } } // send the minted coins to the fee collector account diff --git a/x/mint/keeper/mint_test.go b/x/mint/keeper/mint_test.go index 9f2a493b0853..24d7f8da9f77 100644 --- a/x/mint/keeper/mint_test.go +++ b/x/mint/keeper/mint_test.go @@ -87,7 +87,9 @@ func (s *MintFnTestSuite) TestDefaultMintFn_Success() { s.Require().NoError(err) expectedInflation := types.DefaultInflationCalculationFn(context.TODO(), minter, types.DefaultParams(), bondedRatio) + totalSupply := math.NewInt(1_000_000_000) // Set bank keeper expectations for minting and fee collection. + s.bankKeeper.EXPECT().GetSupply(s.ctx, "stake").Return(sdk.NewCoin("stake", totalSupply)).Times(1) s.bankKeeper.EXPECT().MintCoins(s.ctx, types.ModuleName, expectedCoins).Return(nil).Times(1) s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, types.ModuleName, authtypes.FeeCollectorName, expectedCoins).Return(nil).Times(1) diff --git a/x/mint/keeper/msg_server_test.go b/x/mint/keeper/msg_server_test.go index 83eeae58d39a..e5f6ede33d47 100644 --- a/x/mint/keeper/msg_server_test.go +++ b/x/mint/keeper/msg_server_test.go @@ -53,6 +53,7 @@ func (s *IntegrationTestSuite) TestUpdateParams() { InflationMin: sdkmath.LegacyNewDecWithPrec(2, 2), GoalBonded: sdkmath.LegacyNewDecWithPrec(37, 2), BlocksPerYear: uint64(60 * 60 * 8766 / 5), + MaxSupply: sdkmath.ZeroInt(), // infinite supply }, }, expectErr: false, diff --git a/x/mint/migrations/v3/migrate.go b/x/mint/migrations/v3/migrate.go new file mode 100644 index 000000000000..73960309ae74 --- /dev/null +++ b/x/mint/migrations/v3/migrate.go @@ -0,0 +1,39 @@ +package v3 + +import ( + "cosmossdk.io/collections" + storetypes "cosmossdk.io/core/store" + "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "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 2 to +// version 3. +func Migrate( + ctx sdk.Context, + store storetypes.KVStore, + cdc codec.BinaryCodec, + params collections.Item[types.Params], +) error { + currParams, err := params.Get(ctx) + if err != nil { + return err + } + + currParams.MaxSupply = math.NewInt(0) + if err := currParams.Validate(); err != nil { + return err + } + + bz := cdc.MustMarshal(&currParams) + return store.Set(ParamsKey, bz) +} diff --git a/x/mint/migrations/v3/migrator_test.go b/x/mint/migrations/v3/migrator_test.go new file mode 100644 index 000000000000..90e4f349e86c --- /dev/null +++ b/x/mint/migrations/v3/migrator_test.go @@ -0,0 +1,50 @@ +package v3_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "cosmossdk.io/collections" + storetypes "cosmossdk.io/store/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/mint" + v3 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v3" + "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 TestMigrate(t *testing.T) { + encCfg := moduletestutil.MakeTestEncodingConfig(mint.AppModuleBasic{}) + cdc := encCfg.Codec + + storeKey := storetypes.NewKVStoreKey(v3.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + kvStoreService := runtime.NewKVStoreService(storeKey) + store := kvStoreService.OpenKVStore(ctx) + + sb := collections.NewSchemaBuilder(kvStoreService) + params := collections.NewItem(sb, v3.ParamsKey, "params", codec.CollValue[types.Params](cdc)) + + dp := newMockSubspace(types.DefaultParams()) + require.NoError(t, params.Set(ctx, dp.ps)) + require.NoError(t, v3.Migrate(ctx, store, cdc, params)) + + var res types.Params + bz, err := store.Get(v3.ParamsKey) + require.NoError(t, err) + require.NoError(t, cdc.Unmarshal(bz, &res)) + require.Equal(t, dp.ps, res) +} diff --git a/x/mint/module.go b/x/mint/module.go index d7dffe35f3a0..65587dbec2fc 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -28,7 +28,7 @@ import ( ) // ConsensusVersion defines the current x/mint module consensus version. -const ConsensusVersion = 2 +const ConsensusVersion = 3 var ( _ module.AppModuleBasic = AppModule{} @@ -133,6 +133,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { 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)) } + + if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil { + panic(fmt.Sprintf("failed to migrate x/%s from version 2 to 3: %v", types.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the mint module. It returns diff --git a/x/mint/simulation/genesis.go b/x/mint/simulation/genesis.go index 6b89e0f6f653..8b4b575e134e 100644 --- a/x/mint/simulation/genesis.go +++ b/x/mint/simulation/genesis.go @@ -64,7 +64,7 @@ func RandomizedGenState(simState *module.SimulationState) { mintDenom := simState.BondDenom blocksPerYear := uint64(60 * 60 * 8766 / 5) - params := types.NewParams(mintDenom, inflationRateChange, inflationMax, inflationMin, goalBonded, blocksPerYear) + params := types.NewParams(mintDenom, inflationRateChange, inflationMax, inflationMin, goalBonded, blocksPerYear, math.ZeroInt()) mintGenesis := types.NewGenesisState(types.InitialMinter(inflation), params) simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(mintGenesis) diff --git a/x/mint/testutil/expected_keepers_mocks.go b/x/mint/testutil/expected_keepers_mocks.go index c0d89d611e41..8809c7a9610b 100644 --- a/x/mint/testutil/expected_keepers_mocks.go +++ b/x/mint/testutil/expected_keepers_mocks.go @@ -160,6 +160,20 @@ func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { return m.recorder } +// GetSupply mocks base method. +func (m *MockBankKeeper) GetSupply(ctx context.Context, denom string) types.Coin { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSupply", ctx, denom) + ret0, _ := ret[0].(types.Coin) + return ret0 +} + +// GetSupply indicates an expected call of GetSupply. +func (mr *MockBankKeeperMockRecorder) GetSupply(ctx, denom interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSupply", reflect.TypeOf((*MockBankKeeper)(nil).GetSupply), ctx, denom) +} + // MintCoins mocks base method. func (m *MockBankKeeper) MintCoins(ctx context.Context, name string, amt types.Coins) error { m.ctrl.T.Helper() diff --git a/x/mint/types/expected_keepers.go b/x/mint/types/expected_keepers.go index 82edcc6a2092..b26c4aca0b5e 100644 --- a/x/mint/types/expected_keepers.go +++ b/x/mint/types/expected_keepers.go @@ -29,4 +29,5 @@ type BankKeeper interface { SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error MintCoins(ctx context.Context, name string, amt sdk.Coins) error + GetSupply(ctx context.Context, denom string) sdk.Coin } diff --git a/x/mint/types/mint.pb.go b/x/mint/types/mint.pb.go index 708073628246..b3eeca3b65a2 100644 --- a/x/mint/types/mint.pb.go +++ b/x/mint/types/mint.pb.go @@ -81,6 +81,8 @@ type Params struct { GoalBonded cosmossdk_io_math.LegacyDec `protobuf:"bytes,5,opt,name=goal_bonded,json=goalBonded,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"goal_bonded"` // expected blocks per year BlocksPerYear uint64 `protobuf:"varint,6,opt,name=blocks_per_year,json=blocksPerYear,proto3" json:"blocks_per_year,omitempty"` + // maximum supply for the token + MaxSupply cosmossdk_io_math.Int `protobuf:"bytes,7,opt,name=max_supply,json=maxSupply,proto3,customtype=cosmossdk.io/math.Int" json:"max_supply"` } func (m *Params) Reset() { *m = Params{} } @@ -138,35 +140,37 @@ func init() { func init() { proto.RegisterFile("cosmos/mint/v1beta1/mint.proto", fileDescriptor_2df116d183c1e223) } var fileDescriptor_2df116d183c1e223 = []byte{ - // 436 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xb1, 0x8e, 0xd3, 0x30, - 0x18, 0xc7, 0x63, 0xee, 0x88, 0x54, 0xc3, 0x09, 0xce, 0x07, 0x52, 0x38, 0x74, 0xb9, 0xd3, 0x0d, - 0xe8, 0x38, 0xe9, 0x12, 0x55, 0x48, 0x0c, 0x8c, 0xbd, 0x8e, 0x9c, 0xa8, 0xb2, 0x20, 0x40, 0x22, - 0xfa, 0x92, 0x98, 0xd4, 0x34, 0xb6, 0x2b, 0xdb, 0x57, 0xb5, 0xaf, 0xc0, 0xc4, 0x63, 0x30, 0x76, - 0x60, 0xe1, 0x0d, 0x3a, 0x56, 0x4c, 0x88, 0xa1, 0x42, 0xed, 0xd0, 0x89, 0x77, 0x40, 0x89, 0xa3, - 0x54, 0x82, 0x09, 0xca, 0x12, 0xc5, 0xff, 0xff, 0xe7, 0xdf, 0xf7, 0x97, 0xfd, 0x19, 0xfb, 0xa9, - 0xd4, 0x5c, 0xea, 0x90, 0x33, 0x61, 0xc2, 0x51, 0x3b, 0xa1, 0x06, 0xda, 0xd5, 0x22, 0x18, 0x2a, - 0x69, 0x24, 0x39, 0xb0, 0x7e, 0x50, 0x49, 0xb5, 0x7f, 0x78, 0x2f, 0x97, 0xb9, 0xac, 0xfc, 0xb0, - 0xfc, 0xb3, 0xa5, 0x87, 0x0f, 0x6c, 0x69, 0x6c, 0x8d, 0x7a, 0x9f, 0xb5, 0xf6, 0x81, 0x33, 0x21, - 0xc3, 0xea, 0x6b, 0xa5, 0xd3, 0x2f, 0x08, 0xbb, 0x57, 0x4c, 0x18, 0xaa, 0xc8, 0x0b, 0xdc, 0x62, - 0xe2, 0x5d, 0x01, 0x86, 0x49, 0xe1, 0xa1, 0x13, 0x74, 0xd6, 0xea, 0xb4, 0x67, 0x8b, 0x63, 0xe7, - 0xfb, 0xe2, 0xf8, 0xa1, 0xc5, 0xe8, 0x6c, 0x10, 0x30, 0x19, 0x72, 0x30, 0xfd, 0xe0, 0x39, 0xcd, - 0x21, 0x9d, 0x74, 0x69, 0xfa, 0xf5, 0xf3, 0x05, 0xae, 0xbb, 0x74, 0x69, 0x1a, 0x6d, 0x18, 0xe4, - 0x2d, 0xde, 0x07, 0x21, 0xae, 0xa1, 0x28, 0xb3, 0x8c, 0x98, 0x66, 0x52, 0x68, 0xef, 0xc6, 0xbf, - 0x82, 0xef, 0x5a, 0x56, 0xaf, 0x41, 0x9d, 0xfe, 0xdc, 0xc1, 0x6e, 0x0f, 0x14, 0x70, 0x4d, 0x8e, - 0x30, 0x2e, 0x8f, 0x26, 0xce, 0xa8, 0x90, 0xdc, 0x86, 0x8f, 0x5a, 0xa5, 0xd2, 0x2d, 0x05, 0xf2, - 0x1e, 0xdf, 0x6f, 0x62, 0xc5, 0x0a, 0x0c, 0x8d, 0xd3, 0x3e, 0x88, 0x9c, 0xd6, 0x69, 0x9e, 0xfe, - 0x75, 0x9a, 0x4f, 0xeb, 0xe9, 0x39, 0x8a, 0x0e, 0x1a, 0x68, 0x04, 0x86, 0x5e, 0x56, 0x48, 0xf2, - 0x06, 0xef, 0x6d, 0x7a, 0x71, 0x18, 0x7b, 0x3b, 0x5b, 0xf5, 0xb8, 0xdd, 0xc0, 0xae, 0x60, 0xfc, - 0x1b, 0x9c, 0x09, 0x6f, 0xf7, 0x7f, 0xc1, 0x99, 0x20, 0x2f, 0xf1, 0xad, 0x5c, 0x42, 0x11, 0x27, - 0x52, 0x64, 0x34, 0xf3, 0x6e, 0x6e, 0x85, 0xc6, 0x25, 0xaa, 0x53, 0x91, 0xc8, 0x23, 0x7c, 0x27, - 0x29, 0x64, 0x3a, 0xd0, 0xf1, 0x90, 0xaa, 0x78, 0x42, 0x41, 0x79, 0xee, 0x09, 0x3a, 0xdb, 0x8d, - 0xf6, 0xac, 0xdc, 0xa3, 0xea, 0x15, 0x05, 0xf5, 0xec, 0xe8, 0xc3, 0x7a, 0x7a, 0xee, 0x59, 0xd2, - 0x85, 0xce, 0x06, 0xe1, 0xd8, 0x3e, 0x08, 0x7b, 0xc9, 0x9d, 0xcb, 0xd9, 0xd2, 0x47, 0xf3, 0xa5, - 0x8f, 0x7e, 0x2c, 0x7d, 0xf4, 0x71, 0xe5, 0x3b, 0xf3, 0x95, 0xef, 0x7c, 0x5b, 0xf9, 0xce, 0xeb, - 0xc7, 0x39, 0x33, 0xfd, 0xeb, 0x24, 0x48, 0x25, 0xaf, 0x27, 0x3e, 0xfc, 0x93, 0x62, 0x26, 0x43, - 0xaa, 0x13, 0xb7, 0x9a, 0xfb, 0x27, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc2, 0xd0, 0x42, 0xaf, - 0x72, 0x03, 0x00, 0x00, + // 469 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xc1, 0x6a, 0xd4, 0x40, + 0x1c, 0xc6, 0x37, 0xba, 0xae, 0xec, 0x68, 0xd1, 0x4e, 0x2d, 0xc4, 0x4a, 0xd3, 0xd2, 0x83, 0xd4, + 0x4a, 0x13, 0x16, 0xc1, 0x83, 0xc7, 0xed, 0x5e, 0x2a, 0x16, 0x97, 0x78, 0x10, 0x15, 0x1c, 0xfe, + 0x49, 0xc6, 0xec, 0xb8, 0x99, 0x99, 0x30, 0x33, 0x5b, 0xb2, 0xaf, 0xe0, 0xc9, 0xc7, 0xf0, 0xd8, + 0x83, 0x97, 0xbe, 0x41, 0x8f, 0xc5, 0x93, 0x78, 0x28, 0xb2, 0x7b, 0xe8, 0x6b, 0x48, 0x66, 0xc2, + 0x56, 0xec, 0x49, 0xeb, 0x25, 0x24, 0xdf, 0x37, 0xff, 0xdf, 0xf7, 0x11, 0xe6, 0x8f, 0x82, 0x54, + 0x6a, 0x2e, 0x75, 0xc4, 0x99, 0x30, 0xd1, 0x61, 0x2f, 0xa1, 0x06, 0x7a, 0xf6, 0x23, 0x2c, 0x95, + 0x34, 0x12, 0xaf, 0x38, 0x3f, 0xb4, 0x52, 0xe3, 0xaf, 0xdd, 0xcb, 0x65, 0x2e, 0xad, 0x1f, 0xd5, + 0x6f, 0xee, 0xe8, 0xda, 0x7d, 0x77, 0x94, 0x38, 0xa3, 0x99, 0x73, 0xd6, 0x32, 0x70, 0x26, 0x64, + 0x64, 0x9f, 0x4e, 0xda, 0x3a, 0xf6, 0x50, 0xe7, 0x80, 0x09, 0x43, 0x15, 0x7e, 0x89, 0xba, 0x4c, + 0x7c, 0x28, 0xc0, 0x30, 0x29, 0x7c, 0x6f, 0xd3, 0xdb, 0xee, 0xf6, 0x7b, 0x27, 0x67, 0x1b, 0xad, + 0x1f, 0x67, 0x1b, 0x0f, 0x1c, 0x46, 0x67, 0xe3, 0x90, 0xc9, 0x88, 0x83, 0x19, 0x85, 0x2f, 0x68, + 0x0e, 0xe9, 0x74, 0x40, 0xd3, 0x6f, 0x5f, 0x77, 0x51, 0x93, 0x32, 0xa0, 0x69, 0x7c, 0xc1, 0xc0, + 0xef, 0xd1, 0x32, 0x08, 0x31, 0x81, 0xa2, 0xee, 0x72, 0xc8, 0x34, 0x93, 0x42, 0xfb, 0xd7, 0xfe, + 0x15, 0x7c, 0xd7, 0xb1, 0x86, 0x0b, 0xd4, 0xd6, 0x71, 0x1b, 0x75, 0x86, 0xa0, 0x80, 0x6b, 0xbc, + 0x8e, 0x50, 0xfd, 0x6b, 0x48, 0x46, 0x85, 0xe4, 0xae, 0x7c, 0xdc, 0xad, 0x95, 0x41, 0x2d, 0xe0, + 0x8f, 0x68, 0x75, 0x51, 0x8b, 0x28, 0x30, 0x94, 0xa4, 0x23, 0x10, 0x39, 0x6d, 0xda, 0x3c, 0xfd, + 0xeb, 0x36, 0x5f, 0xce, 0x8f, 0x76, 0xbc, 0x78, 0x65, 0x01, 0x8d, 0xc1, 0xd0, 0x3d, 0x8b, 0xc4, + 0xef, 0xd0, 0xd2, 0x45, 0x16, 0x87, 0xca, 0xbf, 0x7e, 0xa5, 0x8c, 0xdb, 0x0b, 0xd8, 0x01, 0x54, + 0x7f, 0xc0, 0x99, 0xf0, 0xdb, 0xff, 0x0b, 0xce, 0x04, 0x7e, 0x8d, 0x6e, 0xe5, 0x12, 0x0a, 0x92, + 0x48, 0x91, 0xd1, 0xcc, 0xbf, 0x71, 0x25, 0x34, 0xaa, 0x51, 0x7d, 0x4b, 0xc2, 0x0f, 0xd1, 0x9d, + 0xa4, 0x90, 0xe9, 0x58, 0x93, 0x92, 0x2a, 0x32, 0xa5, 0xa0, 0xfc, 0xce, 0xa6, 0xb7, 0xdd, 0x8e, + 0x97, 0x9c, 0x3c, 0xa4, 0xea, 0x0d, 0x05, 0x85, 0x9f, 0x23, 0xc4, 0xa1, 0x22, 0x7a, 0x52, 0x96, + 0xc5, 0xd4, 0xbf, 0x69, 0xf3, 0x1f, 0x37, 0xf9, 0xab, 0x97, 0xf3, 0xf7, 0x85, 0xf9, 0x2d, 0x79, + 0x5f, 0x98, 0xb8, 0xcb, 0xa1, 0x7a, 0x65, 0xa7, 0x9f, 0xad, 0x7f, 0x3a, 0x3f, 0xda, 0xf1, 0x9d, + 0xb7, 0xab, 0xb3, 0x71, 0x54, 0xb9, 0xe5, 0x72, 0x17, 0xa6, 0xbf, 0x77, 0x32, 0x0b, 0xbc, 0xd3, + 0x59, 0xe0, 0xfd, 0x9c, 0x05, 0xde, 0xe7, 0x79, 0xd0, 0x3a, 0x9d, 0x07, 0xad, 0xef, 0xf3, 0xa0, + 0xf5, 0xf6, 0x51, 0xce, 0xcc, 0x68, 0x92, 0x84, 0xa9, 0xe4, 0xcd, 0xf6, 0x44, 0x97, 0x29, 0x66, + 0x5a, 0x52, 0x9d, 0x74, 0xec, 0x0e, 0x3d, 0xf9, 0x15, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x66, 0x4f, + 0x04, 0xbe, 0x03, 0x00, 0x00, } func (m *Minter) Marshal() (dAtA []byte, err error) { @@ -232,6 +236,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.MaxSupply.Size() + i -= size + if _, err := m.MaxSupply.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintMint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a if m.BlocksPerYear != 0 { i = encodeVarintMint(dAtA, i, uint64(m.BlocksPerYear)) i-- @@ -332,6 +346,8 @@ func (m *Params) Size() (n int) { if m.BlocksPerYear != 0 { n += 1 + sovMint(uint64(m.BlocksPerYear)) } + l = m.MaxSupply.Size() + n += 1 + l + sovMint(uint64(l)) return n } @@ -675,6 +691,40 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSupply", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + 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 ErrInvalidLengthMint + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxSupply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMint(dAtA[iNdEx:]) diff --git a/x/mint/types/params.go b/x/mint/types/params.go index b25d5aac7d64..dbe4040c6462 100644 --- a/x/mint/types/params.go +++ b/x/mint/types/params.go @@ -11,7 +11,7 @@ import ( ) // NewParams returns Params instance with the given values. -func NewParams(mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded math.LegacyDec, blocksPerYear uint64) Params { +func NewParams(mintDenom string, inflationRateChange, inflationMax, inflationMin, goalBonded math.LegacyDec, blocksPerYear uint64, maxSupply math.Int) Params { return Params{ MintDenom: mintDenom, InflationRateChange: inflationRateChange, @@ -19,6 +19,7 @@ func NewParams(mintDenom string, inflationRateChange, inflationMax, inflationMin InflationMin: inflationMin, GoalBonded: goalBonded, BlocksPerYear: blocksPerYear, + MaxSupply: maxSupply, } } @@ -31,6 +32,7 @@ func DefaultParams() Params { InflationMin: math.LegacyNewDecWithPrec(7, 2), GoalBonded: math.LegacyNewDecWithPrec(67, 2), BlocksPerYear: uint64(60 * 60 * 8766 / 5), // assuming 5 second block times + MaxSupply: math.ZeroInt(), // assuming zero is infinite } } @@ -54,6 +56,9 @@ func (p Params) Validate() error { if err := validateBlocksPerYear(p.BlocksPerYear); err != nil { return err } + if err := validateMaxSupply(p.MaxSupply); err != nil { + return err + } if p.InflationMax.LT(p.InflationMin) { return fmt.Errorf( "max inflation (%s) must be greater than or equal to min inflation (%s)", @@ -168,3 +173,16 @@ func validateBlocksPerYear(i any) error { return nil } + +func validateMaxSupply(i interface{}) error { + v, ok := i.(math.Int) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.IsNegative() { + return fmt.Errorf("max supply must be positive: %d", v) + } + + return nil +}