From 0fda53f265de4bcf4be1a13ea9fad450fc2e66d4 Mon Sep 17 00:00:00 2001 From: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:07:50 +0200 Subject: [PATCH] feat(x/protocolpool,x/distribution)!: remove dependency + fix continuous fund bug (#20790) --- api/cosmos/protocolpool/v1/genesis.pulsar.go | 1013 ++++++++++++++--- simapp/app.go | 67 +- simapp/app_config.go | 2 + simapp/v2/app_config.go | 2 + .../distribution/keeper/msg_server_test.go | 15 +- tests/integration/gov/keeper/keeper_test.go | 13 +- tests/integration/protocolpool/module_test.go | 5 +- testutil/configurator/configurator.go | 2 + x/distribution/CHANGELOG.md | 8 +- x/distribution/depinject.go | 4 +- x/distribution/go.mod | 1 + x/distribution/go.sum | 2 - x/distribution/keeper/allocation.go | 9 +- x/distribution/keeper/allocation_test.go | 12 +- x/distribution/keeper/delegation_test.go | 18 - x/distribution/keeper/grpc_query.go | 11 +- x/distribution/keeper/grpc_query_test.go | 7 +- x/distribution/keeper/keeper.go | 3 - x/distribution/keeper/keeper_test.go | 5 +- x/distribution/keeper/migrations.go | 2 +- x/distribution/keeper/msg_server.go | 4 +- x/distribution/keeper/msg_server_test.go | 6 +- .../migrations/v4/migrate_funds_test.go | 2 - x/distribution/module.go | 4 +- .../testutil/expected_keepers_mocks.go | 80 -- x/distribution/types/expected_keepers.go | 8 - x/distribution/types/keys.go | 7 +- x/gov/testutil/expected_keepers.go | 2 +- x/gov/testutil/expected_keepers_mocks.go | 2 +- x/gov/types/expected_keepers.go | 2 +- x/protocolpool/CHANGELOG.md | 30 + x/protocolpool/keeper/genesis.go | 33 +- x/protocolpool/keeper/genesis_test.go | 11 + x/protocolpool/keeper/keeper.go | 254 +++-- x/protocolpool/keeper/keeper_test.go | 23 +- x/protocolpool/keeper/msg_server.go | 31 +- x/protocolpool/keeper/msg_server_test.go | 106 +- x/protocolpool/module.go | 6 + .../cosmos/protocolpool/v1/genesis.proto | 20 +- x/protocolpool/types/errors.go | 4 +- x/protocolpool/types/genesis.go | 2 + x/protocolpool/types/genesis.pb.go | 355 +++++- x/protocolpool/types/keys.go | 6 +- 43 files changed, 1646 insertions(+), 553 deletions(-) create mode 100644 x/protocolpool/CHANGELOG.md diff --git a/api/cosmos/protocolpool/v1/genesis.pulsar.go b/api/cosmos/protocolpool/v1/genesis.pulsar.go index 98fc6c28121..3a7ff075f2a 100644 --- a/api/cosmos/protocolpool/v1/genesis.pulsar.go +++ b/api/cosmos/protocolpool/v1/genesis.pulsar.go @@ -9,6 +9,7 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" io "io" reflect "reflect" sync "sync" @@ -116,11 +117,63 @@ func (x *_GenesisState_2_list) IsValid() bool { return x.list != nil } +var _ protoreflect.List = (*_GenesisState_4_list)(nil) + +type _GenesisState_4_list struct { + list *[]*Distribution +} + +func (x *_GenesisState_4_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_GenesisState_4_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_GenesisState_4_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*Distribution) + (*x.list)[i] = concreteValue +} + +func (x *_GenesisState_4_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*Distribution) + *x.list = append(*x.list, concreteValue) +} + +func (x *_GenesisState_4_list) AppendMutable() protoreflect.Value { + v := new(Distribution) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_4_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_GenesisState_4_list) NewElement() protoreflect.Value { + v := new(Distribution) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_4_list) IsValid() bool { + return x.list != nil +} + var ( md_GenesisState protoreflect.MessageDescriptor fd_GenesisState_continuous_fund protoreflect.FieldDescriptor fd_GenesisState_budget protoreflect.FieldDescriptor - fd_GenesisState_to_distribute protoreflect.FieldDescriptor + fd_GenesisState_last_balance protoreflect.FieldDescriptor + fd_GenesisState_distributions protoreflect.FieldDescriptor ) func init() { @@ -128,7 +181,8 @@ func init() { md_GenesisState = File_cosmos_protocolpool_v1_genesis_proto.Messages().ByName("GenesisState") fd_GenesisState_continuous_fund = md_GenesisState.Fields().ByName("continuous_fund") fd_GenesisState_budget = md_GenesisState.Fields().ByName("budget") - fd_GenesisState_to_distribute = md_GenesisState.Fields().ByName("to_distribute") + fd_GenesisState_last_balance = md_GenesisState.Fields().ByName("last_balance") + fd_GenesisState_distributions = md_GenesisState.Fields().ByName("distributions") } var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) @@ -208,9 +262,15 @@ func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, return } } - if x.ToDistribute != "" { - value := protoreflect.ValueOfString(x.ToDistribute) - if !f(fd_GenesisState_to_distribute, value) { + if x.LastBalance != "" { + value := protoreflect.ValueOfString(x.LastBalance) + if !f(fd_GenesisState_last_balance, value) { + return + } + } + if len(x.Distributions) != 0 { + value := protoreflect.ValueOfList(&_GenesisState_4_list{list: &x.Distributions}) + if !f(fd_GenesisState_distributions, value) { return } } @@ -233,8 +293,10 @@ func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool return len(x.ContinuousFund) != 0 case "cosmos.protocolpool.v1.GenesisState.budget": return len(x.Budget) != 0 - case "cosmos.protocolpool.v1.GenesisState.to_distribute": - return x.ToDistribute != "" + case "cosmos.protocolpool.v1.GenesisState.last_balance": + return x.LastBalance != "" + case "cosmos.protocolpool.v1.GenesisState.distributions": + return len(x.Distributions) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -255,8 +317,10 @@ func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { x.ContinuousFund = nil case "cosmos.protocolpool.v1.GenesisState.budget": x.Budget = nil - case "cosmos.protocolpool.v1.GenesisState.to_distribute": - x.ToDistribute = "" + case "cosmos.protocolpool.v1.GenesisState.last_balance": + x.LastBalance = "" + case "cosmos.protocolpool.v1.GenesisState.distributions": + x.Distributions = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -285,9 +349,15 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto } listValue := &_GenesisState_2_list{list: &x.Budget} return protoreflect.ValueOfList(listValue) - case "cosmos.protocolpool.v1.GenesisState.to_distribute": - value := x.ToDistribute + case "cosmos.protocolpool.v1.GenesisState.last_balance": + value := x.LastBalance return protoreflect.ValueOfString(value) + case "cosmos.protocolpool.v1.GenesisState.distributions": + if len(x.Distributions) == 0 { + return protoreflect.ValueOfList(&_GenesisState_4_list{}) + } + listValue := &_GenesisState_4_list{list: &x.Distributions} + return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -316,8 +386,12 @@ func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value lv := value.List() clv := lv.(*_GenesisState_2_list) x.Budget = *clv.list - case "cosmos.protocolpool.v1.GenesisState.to_distribute": - x.ToDistribute = value.Interface().(string) + case "cosmos.protocolpool.v1.GenesisState.last_balance": + x.LastBalance = value.Interface().(string) + case "cosmos.protocolpool.v1.GenesisState.distributions": + lv := value.List() + clv := lv.(*_GenesisState_4_list) + x.Distributions = *clv.list default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -350,8 +424,14 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p } value := &_GenesisState_2_list{list: &x.Budget} return protoreflect.ValueOfList(value) - case "cosmos.protocolpool.v1.GenesisState.to_distribute": - panic(fmt.Errorf("field to_distribute of message cosmos.protocolpool.v1.GenesisState is not mutable")) + case "cosmos.protocolpool.v1.GenesisState.distributions": + if x.Distributions == nil { + x.Distributions = []*Distribution{} + } + value := &_GenesisState_4_list{list: &x.Distributions} + return protoreflect.ValueOfList(value) + case "cosmos.protocolpool.v1.GenesisState.last_balance": + panic(fmt.Errorf("field last_balance of message cosmos.protocolpool.v1.GenesisState is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -371,8 +451,11 @@ func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) case "cosmos.protocolpool.v1.GenesisState.budget": list := []*Budget{} return protoreflect.ValueOfList(&_GenesisState_2_list{list: &list}) - case "cosmos.protocolpool.v1.GenesisState.to_distribute": + case "cosmos.protocolpool.v1.GenesisState.last_balance": return protoreflect.ValueOfString("") + case "cosmos.protocolpool.v1.GenesisState.distributions": + list := []*Distribution{} + return protoreflect.ValueOfList(&_GenesisState_4_list{list: &list}) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.GenesisState")) @@ -454,10 +537,16 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { n += 1 + l + runtime.Sov(uint64(l)) } } - l = len(x.ToDistribute) + l = len(x.LastBalance) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + if len(x.Distributions) > 0 { + for _, e := range x.Distributions { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -487,10 +576,26 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.ToDistribute) > 0 { - i -= len(x.ToDistribute) - copy(dAtA[i:], x.ToDistribute) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ToDistribute))) + if len(x.Distributions) > 0 { + for iNdEx := len(x.Distributions) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Distributions[iNdEx]) + 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] = 0x22 + } + } + if len(x.LastBalance) > 0 { + i -= len(x.LastBalance) + copy(dAtA[i:], x.LastBalance) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.LastBalance))) i-- dAtA[i] = 0x1a } @@ -645,7 +750,7 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 3: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ToDistribute", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field LastBalance", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -673,7 +778,41 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.ToDistribute = string(dAtA[iNdEx:postIndex]) + x.LastBalance = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Distributions", 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 + } + x.Distributions = append(x.Distributions, &Distribution{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Distributions[len(x.Distributions)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } iNdEx = postIndex default: iNdEx = preIndex @@ -710,154 +849,740 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { } } -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: cosmos/protocolpool/v1/genesis.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) +var ( + md_Distribution protoreflect.MessageDescriptor + fd_Distribution_amount protoreflect.FieldDescriptor + fd_Distribution_time protoreflect.FieldDescriptor ) -// GenesisState defines the protocolpool module's genesis state. -type GenesisState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +func init() { + file_cosmos_protocolpool_v1_genesis_proto_init() + md_Distribution = File_cosmos_protocolpool_v1_genesis_proto.Messages().ByName("Distribution") + fd_Distribution_amount = md_Distribution.Fields().ByName("amount") + fd_Distribution_time = md_Distribution.Fields().ByName("time") +} - // ContinuousFund defines the continuous funds at genesis. - ContinuousFund []*ContinuousFund `protobuf:"bytes,1,rep,name=continuous_fund,json=continuousFund,proto3" json:"continuous_fund,omitempty"` - // Budget defines the budget proposals at genesis. - Budget []*Budget `protobuf:"bytes,2,rep,name=budget,proto3" json:"budget,omitempty"` - ToDistribute string `protobuf:"bytes,3,opt,name=to_distribute,json=toDistribute,proto3" json:"to_distribute,omitempty"` +var _ protoreflect.Message = (*fastReflection_Distribution)(nil) + +type fastReflection_Distribution Distribution + +func (x *Distribution) ProtoReflect() protoreflect.Message { + return (*fastReflection_Distribution)(x) } -func (x *GenesisState) Reset() { - *x = GenesisState{} - if protoimpl.UnsafeEnabled { - mi := &file_cosmos_protocolpool_v1_genesis_proto_msgTypes[0] +func (x *Distribution) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_protocolpool_v1_genesis_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } + return mi.MessageOf(x) } -func (x *GenesisState) String() string { - return protoimpl.X.MessageStringOf(x) -} +var _fastReflection_Distribution_messageType fastReflection_Distribution_messageType +var _ protoreflect.MessageType = fastReflection_Distribution_messageType{} -func (*GenesisState) ProtoMessage() {} +type fastReflection_Distribution_messageType struct{} -// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. -func (*GenesisState) Descriptor() ([]byte, []int) { - return file_cosmos_protocolpool_v1_genesis_proto_rawDescGZIP(), []int{0} +func (x fastReflection_Distribution_messageType) Zero() protoreflect.Message { + return (*fastReflection_Distribution)(nil) } - -func (x *GenesisState) GetContinuousFund() []*ContinuousFund { - if x != nil { - return x.ContinuousFund - } - return nil +func (x fastReflection_Distribution_messageType) New() protoreflect.Message { + return new(fastReflection_Distribution) +} +func (x fastReflection_Distribution_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Distribution } -func (x *GenesisState) GetBudget() []*Budget { - if x != nil { - return x.Budget - } - return nil +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Distribution) Descriptor() protoreflect.MessageDescriptor { + return md_Distribution } -func (x *GenesisState) GetToDistribute() string { - if x != nil { - return x.ToDistribute - } - return "" +// 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_Distribution) Type() protoreflect.MessageType { + return _fastReflection_Distribution_messageType } -var File_cosmos_protocolpool_v1_genesis_proto protoreflect.FileDescriptor +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Distribution) New() protoreflect.Message { + return new(fastReflection_Distribution) +} -var file_cosmos_protocolpool_v1_genesis_proto_rawDesc = []byte{ - 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x1a, 0x22, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, - 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 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, 0xe9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, - 0x75, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, - 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x46, 0x75, 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x46, 0x75, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x42, - 0x75, 0x64, 0x67, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x12, 0x50, 0x0a, - 0x0d, 0x74, 0x6f, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x03, - 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, 0x0c, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, - 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x0c, - 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x70, 0x6f, 0x6f, 0x6c, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x50, 0x58, 0xaa, 0x02, 0x16, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, - 0x6f, 0x6c, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x5c, 0x56, 0x31, 0xe2, 0x02, - 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x70, 0x6f, 0x6f, 0x6c, 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, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Distribution) Interface() protoreflect.ProtoMessage { + return (*Distribution)(x) } -var ( - file_cosmos_protocolpool_v1_genesis_proto_rawDescOnce sync.Once - file_cosmos_protocolpool_v1_genesis_proto_rawDescData = file_cosmos_protocolpool_v1_genesis_proto_rawDesc -) +// 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_Distribution) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Amount != "" { + value := protoreflect.ValueOfString(x.Amount) + if !f(fd_Distribution_amount, value) { + return + } + } + if x.Time != nil { + value := protoreflect.ValueOfMessage(x.Time.ProtoReflect()) + if !f(fd_Distribution_time, value) { + return + } + } +} -func file_cosmos_protocolpool_v1_genesis_proto_rawDescGZIP() []byte { - file_cosmos_protocolpool_v1_genesis_proto_rawDescOnce.Do(func() { - file_cosmos_protocolpool_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_protocolpool_v1_genesis_proto_rawDescData) - }) - return file_cosmos_protocolpool_v1_genesis_proto_rawDescData +// 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_Distribution) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.protocolpool.v1.Distribution.amount": + return x.Amount != "" + case "cosmos.protocolpool.v1.Distribution.time": + return x.Time != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution does not contain field %s", fd.FullName())) + } } -var file_cosmos_protocolpool_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_cosmos_protocolpool_v1_genesis_proto_goTypes = []interface{}{ - (*GenesisState)(nil), // 0: cosmos.protocolpool.v1.GenesisState - (*ContinuousFund)(nil), // 1: cosmos.protocolpool.v1.ContinuousFund - (*Budget)(nil), // 2: cosmos.protocolpool.v1.Budget +// 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_Distribution) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.protocolpool.v1.Distribution.amount": + x.Amount = "" + case "cosmos.protocolpool.v1.Distribution.time": + x.Time = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution does not contain field %s", fd.FullName())) + } } -var file_cosmos_protocolpool_v1_genesis_proto_depIdxs = []int32{ - 1, // 0: cosmos.protocolpool.v1.GenesisState.continuous_fund:type_name -> cosmos.protocolpool.v1.ContinuousFund - 2, // 1: cosmos.protocolpool.v1.GenesisState.budget:type_name -> cosmos.protocolpool.v1.Budget - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + +// 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_Distribution) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.protocolpool.v1.Distribution.amount": + value := x.Amount + return protoreflect.ValueOfString(value) + case "cosmos.protocolpool.v1.Distribution.time": + value := x.Time + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution does not contain field %s", descriptor.FullName())) + } } -func init() { file_cosmos_protocolpool_v1_genesis_proto_init() } -func file_cosmos_protocolpool_v1_genesis_proto_init() { - if File_cosmos_protocolpool_v1_genesis_proto != nil { - return +// 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_Distribution) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.protocolpool.v1.Distribution.amount": + x.Amount = value.Interface().(string) + case "cosmos.protocolpool.v1.Distribution.time": + x.Time = value.Message().Interface().(*timestamppb.Timestamp) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution does not contain field %s", fd.FullName())) } - file_cosmos_protocolpool_v1_types_proto_init() - if !protoimpl.UnsafeEnabled { - file_cosmos_protocolpool_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GenesisState); i { +} + +// 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_Distribution) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.protocolpool.v1.Distribution.time": + if x.Time == nil { + x.Time = new(timestamppb.Timestamp) + } + return protoreflect.ValueOfMessage(x.Time.ProtoReflect()) + case "cosmos.protocolpool.v1.Distribution.amount": + panic(fmt.Errorf("field amount of message cosmos.protocolpool.v1.Distribution is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution 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_Distribution) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.protocolpool.v1.Distribution.amount": + return protoreflect.ValueOfString("") + case "cosmos.protocolpool.v1.Distribution.time": + m := new(timestamppb.Timestamp) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.Distribution")) + } + panic(fmt.Errorf("message cosmos.protocolpool.v1.Distribution 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_Distribution) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.protocolpool.v1.Distribution", 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_Distribution) 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_Distribution) 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_Distribution) 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_Distribution) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Distribution) + 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.Amount) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Time != nil { + l = options.Size(x.Time) + 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().(*Distribution) + 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.Time != nil { + encoded, err := options.Marshal(x.Time) + 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] = 0x32 + } + if len(x.Amount) > 0 { + i -= len(x.Amount) + copy(dAtA[i:], x.Amount) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Amount))) + i-- + dAtA[i] = 0x1a + } + 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().(*Distribution) + 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: Distribution: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Distribution: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Amount", 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.Amount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Time", 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.Time == nil { + x.Time = ×tamppb.Timestamp{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Time); 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, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: cosmos/protocolpool/v1/genesis.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) +) + +// GenesisState defines the protocolpool module's genesis state. +type GenesisState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ContinuousFund defines the continuous funds at genesis. + ContinuousFund []*ContinuousFund `protobuf:"bytes,1,rep,name=continuous_fund,json=continuousFund,proto3" json:"continuous_fund,omitempty"` + // Budget defines the budget proposals at genesis. + Budget []*Budget `protobuf:"bytes,2,rep,name=budget,proto3" json:"budget,omitempty"` + // last_balance contains the amount of tokens yet to be distributed, will be zero if + // there are no funds to distribute. + LastBalance string `protobuf:"bytes,3,opt,name=last_balance,json=lastBalance,proto3" json:"last_balance,omitempty"` + // distributions contains the list of distributions to be made to continuous + // funds and budgets. It contains time in order to distribute to non-expired + // funds only. + Distributions []*Distribution `protobuf:"bytes,4,rep,name=distributions,proto3" json:"distributions,omitempty"` +} + +func (x *GenesisState) Reset() { + *x = GenesisState{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_protocolpool_v1_genesis_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisState) ProtoMessage() {} + +// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. +func (*GenesisState) Descriptor() ([]byte, []int) { + return file_cosmos_protocolpool_v1_genesis_proto_rawDescGZIP(), []int{0} +} + +func (x *GenesisState) GetContinuousFund() []*ContinuousFund { + if x != nil { + return x.ContinuousFund + } + return nil +} + +func (x *GenesisState) GetBudget() []*Budget { + if x != nil { + return x.Budget + } + return nil +} + +func (x *GenesisState) GetLastBalance() string { + if x != nil { + return x.LastBalance + } + return "" +} + +func (x *GenesisState) GetDistributions() []*Distribution { + if x != nil { + return x.Distributions + } + return nil +} + +type Distribution struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` + Time *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=time,proto3" json:"time,omitempty"` +} + +func (x *Distribution) Reset() { + *x = Distribution{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_protocolpool_v1_genesis_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Distribution) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Distribution) ProtoMessage() {} + +// Deprecated: Use Distribution.ProtoReflect.Descriptor instead. +func (*Distribution) Descriptor() ([]byte, []int) { + return file_cosmos_protocolpool_v1_genesis_proto_rawDescGZIP(), []int{1} +} + +func (x *Distribution) GetAmount() string { + if x != nil { + return x.Amount + } + return "" +} + +func (x *Distribution) GetTime() *timestamppb.Timestamp { + if x != nil { + return x.Time + } + return nil +} + +var File_cosmos_protocolpool_v1_genesis_proto protoreflect.FileDescriptor + +var file_cosmos_protocolpool_v1_genesis_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x1a, 0x22, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, + 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 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, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x6f, 0x75, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x46, 0x75, 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x46, 0x75, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x12, 0x4e, + 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, + 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, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4a, + 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x69, 0x73, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x0c, 0x44, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 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, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x34, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, + 0x6f, 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x76, 0x31, 0xa2, 0x02, 0x03, + 0x43, 0x50, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x16, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, + 0x6f, 0x6c, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, 0x6c, 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, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x70, 0x6f, 0x6f, + 0x6c, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_protocolpool_v1_genesis_proto_rawDescOnce sync.Once + file_cosmos_protocolpool_v1_genesis_proto_rawDescData = file_cosmos_protocolpool_v1_genesis_proto_rawDesc +) + +func file_cosmos_protocolpool_v1_genesis_proto_rawDescGZIP() []byte { + file_cosmos_protocolpool_v1_genesis_proto_rawDescOnce.Do(func() { + file_cosmos_protocolpool_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_protocolpool_v1_genesis_proto_rawDescData) + }) + return file_cosmos_protocolpool_v1_genesis_proto_rawDescData +} + +var file_cosmos_protocolpool_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_protocolpool_v1_genesis_proto_goTypes = []interface{}{ + (*GenesisState)(nil), // 0: cosmos.protocolpool.v1.GenesisState + (*Distribution)(nil), // 1: cosmos.protocolpool.v1.Distribution + (*ContinuousFund)(nil), // 2: cosmos.protocolpool.v1.ContinuousFund + (*Budget)(nil), // 3: cosmos.protocolpool.v1.Budget + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp +} +var file_cosmos_protocolpool_v1_genesis_proto_depIdxs = []int32{ + 2, // 0: cosmos.protocolpool.v1.GenesisState.continuous_fund:type_name -> cosmos.protocolpool.v1.ContinuousFund + 3, // 1: cosmos.protocolpool.v1.GenesisState.budget:type_name -> cosmos.protocolpool.v1.Budget + 1, // 2: cosmos.protocolpool.v1.GenesisState.distributions:type_name -> cosmos.protocolpool.v1.Distribution + 4, // 3: cosmos.protocolpool.v1.Distribution.time:type_name -> google.protobuf.Timestamp + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_cosmos_protocolpool_v1_genesis_proto_init() } +func file_cosmos_protocolpool_v1_genesis_proto_init() { + if File_cosmos_protocolpool_v1_genesis_proto != nil { + return + } + file_cosmos_protocolpool_v1_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_cosmos_protocolpool_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenesisState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_protocolpool_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Distribution); i { case 0: return &v.state case 1: @@ -875,7 +1600,7 @@ func file_cosmos_protocolpool_v1_genesis_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_protocolpool_v1_genesis_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/simapp/app.go b/simapp/app.go index 96366c85abc..df3e524922d 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -19,7 +19,6 @@ import ( reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "cosmossdk.io/client/v2/autocli" clienthelpers "cosmossdk.io/client/v2/helpers" - "cosmossdk.io/core/appmodule" "cosmossdk.io/core/log" storetypes "cosmossdk.io/store/types" "cosmossdk.io/x/accounts" @@ -124,15 +123,16 @@ var ( // module account permissions maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, - pooltypes.ModuleName: nil, - pooltypes.StreamAccount: nil, - minttypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - govtypes.ModuleName: {authtypes.Burner}, - nft.ModuleName: nil, + authtypes.FeeCollectorName: nil, + distrtypes.ModuleName: nil, + pooltypes.ModuleName: nil, + pooltypes.StreamAccount: nil, + pooltypes.ProtocolPoolDistrAccount: nil, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + govtypes.ModuleName: {authtypes.Burner}, + nft.ModuleName: nil, } ) @@ -354,7 +354,7 @@ func NewSimApp( app.PoolKeeper = poolkeeper.NewKeeper(appCodec, runtime.NewEnvironment(runtime.NewKVStoreService(keys[pooltypes.StoreKey]), logger.With(log.ModuleKey, "x/protocolpool")), app.AuthKeeper, app.BankKeeper, app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewEnvironment(runtime.NewKVStoreService(keys[distrtypes.StoreKey]), logger.With(log.ModuleKey, "x/distribution")), app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper, cometService, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewEnvironment(runtime.NewKVStoreService(keys[distrtypes.StoreKey]), logger.With(log.ModuleKey, "x/distribution")), app.AuthKeeper, app.BankKeeper, app.StakingKeeper, cometService, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) app.SlashingKeeper = slashingkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), logger.With(log.ModuleKey, "x/slashing")), appCodec, legacyAmino, app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), @@ -437,28 +437,28 @@ func NewSimApp( // NOTE: Any module instantiated in the module manager that is later modified // must be passed by reference here. - app.ModuleManager = module.NewManagerFromMap(map[string]appmodule.AppModule{ - genutiltypes.ModuleName: genutil.NewAppModule(appCodec, app.AuthKeeper, app.StakingKeeper, app, txConfig, genutiltypes.DefaultMessageValidator), - accounts.ModuleName: accounts.NewAppModule(appCodec, app.AccountsKeeper), - authtypes.ModuleName: auth.NewAppModule(appCodec, app.AuthKeeper, app.AccountsKeeper, authsims.RandomGenesisAccounts), - vestingtypes.ModuleName: vesting.NewAppModule(app.AuthKeeper, app.BankKeeper), - banktypes.ModuleName: bank.NewAppModule(appCodec, app.BankKeeper, app.AuthKeeper), - feegrant.ModuleName: feegrantmodule.NewAppModule(appCodec, app.AuthKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - govtypes.ModuleName: gov.NewAppModule(appCodec, &app.GovKeeper, app.AuthKeeper, app.BankKeeper, app.PoolKeeper), - minttypes.ModuleName: mint.NewAppModule(appCodec, app.MintKeeper, app.AuthKeeper, nil), - slashingtypes.ModuleName: slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.interfaceRegistry, cometService), - distrtypes.ModuleName: distr.NewAppModule(appCodec, app.DistrKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper), - stakingtypes.ModuleName: staking.NewAppModule(appCodec, app.StakingKeeper, app.AuthKeeper, app.BankKeeper), - upgradetypes.ModuleName: upgrade.NewAppModule(app.UpgradeKeeper), - evidencetypes.ModuleName: evidence.NewAppModule(appCodec, app.EvidenceKeeper, cometService), - authz.ModuleName: authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), - group.ModuleName: groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), - nft.ModuleName: nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), - consensusparamtypes.ModuleName: consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), - circuittypes.ModuleName: circuit.NewAppModule(appCodec, app.CircuitKeeper), - pooltypes.ModuleName: protocolpool.NewAppModule(appCodec, app.PoolKeeper, app.AuthKeeper, app.BankKeeper), - epochstypes.ModuleName: epochs.NewAppModule(appCodec, app.EpochsKeeper), - }) + app.ModuleManager = module.NewManager( + genutil.NewAppModule(appCodec, app.AuthKeeper, app.StakingKeeper, app, txConfig, genutiltypes.DefaultMessageValidator), + accounts.NewAppModule(appCodec, app.AccountsKeeper), + auth.NewAppModule(appCodec, app.AuthKeeper, app.AccountsKeeper, authsims.RandomGenesisAccounts), + vesting.NewAppModule(app.AuthKeeper, app.BankKeeper), + bank.NewAppModule(appCodec, app.BankKeeper, app.AuthKeeper), + feegrantmodule.NewAppModule(appCodec, app.AuthKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + gov.NewAppModule(appCodec, &app.GovKeeper, app.AuthKeeper, app.BankKeeper, app.PoolKeeper), + mint.NewAppModule(appCodec, app.MintKeeper, app.AuthKeeper, nil), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.interfaceRegistry, cometService), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AuthKeeper, app.BankKeeper), + upgrade.NewAppModule(app.UpgradeKeeper), + evidence.NewAppModule(appCodec, app.EvidenceKeeper, cometService), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), + groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), + nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry), + consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), + circuit.NewAppModule(appCodec, app.CircuitKeeper), + protocolpool.NewAppModule(appCodec, app.PoolKeeper, app.AuthKeeper, app.BankKeeper), + epochs.NewAppModule(appCodec, app.EpochsKeeper), + ) app.ModuleManager.RegisterLegacyAminoCodec(legacyAmino) app.ModuleManager.RegisterInterfaces(interfaceRegistry) @@ -474,6 +474,7 @@ func NewSimApp( app.ModuleManager.SetOrderBeginBlockers( minttypes.ModuleName, distrtypes.ModuleName, + pooltypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, diff --git a/simapp/app_config.go b/simapp/app_config.go index 4eb39f1766c..e92ac2ce03f 100644 --- a/simapp/app_config.go +++ b/simapp/app_config.go @@ -81,6 +81,7 @@ var ( {Account: distrtypes.ModuleName}, {Account: pooltypes.ModuleName}, {Account: pooltypes.StreamAccount}, + {Account: pooltypes.ProtocolPoolDistrAccount}, {Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}}, {Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, {Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, @@ -119,6 +120,7 @@ var ( BeginBlockers: []string{ minttypes.ModuleName, distrtypes.ModuleName, + pooltypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, diff --git a/simapp/v2/app_config.go b/simapp/v2/app_config.go index aff5f923093..c3e5e049293 100644 --- a/simapp/v2/app_config.go +++ b/simapp/v2/app_config.go @@ -77,6 +77,7 @@ var ( {Account: distrtypes.ModuleName}, {Account: pooltypes.ModuleName}, {Account: pooltypes.StreamAccount}, + {Account: pooltypes.ProtocolPoolDistrAccount}, {Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}}, {Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, {Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}}, @@ -115,6 +116,7 @@ var ( BeginBlockers: []string{ minttypes.ModuleName, distrtypes.ModuleName, + pooltypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, diff --git a/tests/integration/distribution/keeper/msg_server_test.go b/tests/integration/distribution/keeper/msg_server_test.go index f8dc1786240..9a85cac995e 100644 --- a/tests/integration/distribution/keeper/msg_server_test.go +++ b/tests/integration/distribution/keeper/msg_server_test.go @@ -86,11 +86,12 @@ func initFixture(t *testing.T) *fixture { authority := authtypes.NewModuleAddress("gov") maccPerms := map[string][]string{ - pooltypes.ModuleName: {}, - pooltypes.StreamAccount: {}, - distrtypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + pooltypes.ModuleName: {}, + pooltypes.StreamAccount: {}, + pooltypes.ProtocolPoolDistrAccount: {}, + distrtypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, } // gomock initializations @@ -137,13 +138,13 @@ func initFixture(t *testing.T) *fixture { poolKeeper := poolkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[pooltypes.StoreKey]), log.NewNopLogger()), accountKeeper, bankKeeper, stakingKeeper, authority.String()) distrKeeper := distrkeeper.NewKeeper( - cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[distrtypes.StoreKey]), logger), accountKeeper, bankKeeper, stakingKeeper, poolKeeper, cometService, distrtypes.ModuleName, authority.String(), + cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[distrtypes.StoreKey]), logger), accountKeeper, bankKeeper, stakingKeeper, cometService, distrtypes.ModuleName, authority.String(), ) authModule := auth.NewAppModule(cdc, accountKeeper, acctsModKeeper, authsims.RandomGenesisAccounts) bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper) stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper) - distrModule := distribution.NewAppModule(cdc, distrKeeper, accountKeeper, bankKeeper, stakingKeeper, poolKeeper) + distrModule := distribution.NewAppModule(cdc, distrKeeper, accountKeeper, bankKeeper, stakingKeeper) poolModule := protocolpool.NewAppModule(cdc, poolKeeper, accountKeeper, bankKeeper) addr := sdk.AccAddress(PKS[0].Address()) diff --git a/tests/integration/gov/keeper/keeper_test.go b/tests/integration/gov/keeper/keeper_test.go index d98e86c06dd..bb2f58979ed 100644 --- a/tests/integration/gov/keeper/keeper_test.go +++ b/tests/integration/gov/keeper/keeper_test.go @@ -67,12 +67,13 @@ func initFixture(tb testing.TB) *fixture { authority := authtypes.NewModuleAddress(types.ModuleName) maccPerms := map[string][]string{ - pooltypes.ModuleName: {}, - pooltypes.StreamAccount: {}, - minttypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - types.ModuleName: {authtypes.Burner}, + pooltypes.ModuleName: {}, + pooltypes.StreamAccount: {}, + pooltypes.ProtocolPoolDistrAccount: {}, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + types.ModuleName: {authtypes.Burner}, } // gomock initializations diff --git a/tests/integration/protocolpool/module_test.go b/tests/integration/protocolpool/module_test.go index 2c527dd0d52..b8148be3710 100644 --- a/tests/integration/protocolpool/module_test.go +++ b/tests/integration/protocolpool/module_test.go @@ -87,7 +87,6 @@ func TestWithdrawAnytime(t *testing.T) { // TestExpireInTheMiddle tests if a continuous fund that expires without anyone // calling the withdraw function, the funds are still distributed correctly. func TestExpireInTheMiddle(t *testing.T) { - t.Skip("This is a bug @facu found, will fix in another PR") var accountKeeper authkeeper.AccountKeeper var protocolpoolKeeper protocolpoolkeeper.Keeper var bankKeeper bankkeeper.Keeper @@ -131,8 +130,8 @@ func TestExpireInTheMiddle(t *testing.T) { _, err = msgServer.WithdrawContinuousFund(ctx, &protocolpooltypes.MsgWithdrawContinuousFund{ RecipientAddress: testAddr0Str, }) - require.Error(t, err) + require.NoError(t, err) endBalance := bankKeeper.GetBalance(ctx, testAddrs[0], sdk.DefaultBondDenom) - require.Equal(t, "158441stake", endBalance.String()) + require.Equal(t, "237661stake", endBalance.String()) } diff --git a/testutil/configurator/configurator.go b/testutil/configurator/configurator.go index 84e1fc986c4..91c93ba2d5b 100644 --- a/testutil/configurator/configurator.go +++ b/testutil/configurator/configurator.go @@ -50,6 +50,7 @@ func defaultConfig() *Config { BeginBlockersOrder: []string{ testutil.MintModuleName, testutil.DistributionModuleName, + testutil.ProtocolPoolModuleName, testutil.SlashingModuleName, testutil.EvidenceModuleName, testutil.StakingModuleName, @@ -164,6 +165,7 @@ func AuthModule() ModuleOption { {Account: testutil.NFTModuleName}, {Account: testutil.ProtocolPoolModuleName}, {Account: "stream_acc"}, + {Account: "protocolpool_distr"}, }, }), } diff --git a/x/distribution/CHANGELOG.md b/x/distribution/CHANGELOG.md index 86940a5e2d8..0a341876bc9 100644 --- a/x/distribution/CHANGELOG.md +++ b/x/distribution/CHANGELOG.md @@ -29,9 +29,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ * -### API Breaking Changes +### Improvements +* [#20790](https://github.com/cosmos/cosmos-sdk/pull/20790) `x/distribution` does not depend on `x/protocolpool` anymore, now `x/distribution` only does token transfers and `x/protocolpool` does the rest. + +### API Breaking Changes +* [#20790](https://github.com/cosmos/cosmos-sdk/pull/20790) `x/distribution` does not depend on `x/protocolpool` anymore, meaning NewAppModule and NewKeeper do not take it as an argument. * [#20588](https://github.com/cosmos/cosmos-sdk/pull/20588) `x/distribution` now takes cometService in order to get consensus related information. * [#19868](https://github.com/cosmos/cosmos-sdk/pull/19868) Removes Accounts String method * `NewMsgSetWithdrawAddress` now takes strings as argument instead of `sdk.AccAddress`. @@ -52,7 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * remove `Keeper`: `SetDelegatorWithdrawAddr`, `DeleteDelegatorWithdrawAddr`, `IterateDelegatorWithdrawAddrs`. * [#16459](https://github.com/cosmos/cosmos-sdk/pull/16459) use collections for `ValidatorCurrentRewards` state management: * remove `Keeper`: `IterateValidatorCurrentRewards`, `GetValidatorCurrentRewards`, `SetValidatorCurrentRewards`, `DeleteValidatorCurrentRewards` -* [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) The distribution module keeper now takes a new argument `PoolKeeper` in addition. +* [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) ~The distribution module keeper now takes a new argument `PoolKeeper` in addition.~ Reverted on #20790 * [#17670](https://github.com/cosmos/cosmos-sdk/pull/17670) `AllocateTokens` takes `comet.VoteInfos` instead of `[]abci.VoteInfo` * [#19740](https://github.com/cosmos/cosmos-sdk/pull/19740) `InitGenesis` and `ExportGenesis` module code and keeper code do not panic but return errors. diff --git a/x/distribution/depinject.go b/x/distribution/depinject.go index ddd6c64b33b..07e63548efa 100644 --- a/x/distribution/depinject.go +++ b/x/distribution/depinject.go @@ -36,7 +36,6 @@ type ModuleInputs struct { AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper StakingKeeper types.StakingKeeper - PoolKeeper types.PoolKeeper } type ModuleOutputs struct { @@ -70,13 +69,12 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { in.AccountKeeper, in.BankKeeper, in.StakingKeeper, - in.PoolKeeper, in.CometService, feeCollectorName, authorityAddr, ) - m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, in.PoolKeeper) + m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper) return ModuleOutputs{ DistrKeeper: k, diff --git a/x/distribution/go.mod b/x/distribution/go.mod index a429835f472..420cfda6f63 100644 --- a/x/distribution/go.mod +++ b/x/distribution/go.mod @@ -187,6 +187,7 @@ replace ( cosmossdk.io/x/auth => ../auth cosmossdk.io/x/bank => ../bank cosmossdk.io/x/consensus => ../consensus + cosmossdk.io/x/protocolpool => ../protocolpool cosmossdk.io/x/staking => ../staking cosmossdk.io/x/tx => ../tx ) diff --git a/x/distribution/go.sum b/x/distribution/go.sum index 58a04eb3afe..4879cfa3455 100644 --- a/x/distribution/go.sum +++ b/x/distribution/go.sum @@ -14,8 +14,6 @@ cosmossdk.io/schema v0.1.1 h1:I0M6pgI7R10nq+/HCQfbO6BsGBZA8sQy+duR1Y3aKcA= cosmossdk.io/schema v0.1.1/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc h1:R9O9d75e0qZYUsVV0zzi+D7cNLnX2JrUOQNoIPaF0Bg= cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc/go.mod h1:amTTatOUV3u1PsKmNb87z6/galCxrRbz9kRdJkL0DyU= -cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= -cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index 992c487ddb4..123b161c0b5 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -79,12 +79,7 @@ func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bo } // send to community pool and set remainder in fee pool amt, re := remaining.TruncateDecimal() - if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.ProtocolPoolModuleName, amt); err != nil { - return err - } - - // set ToDistribute in protocolpool to keep track of continuous funds distribution - if err := k.poolKeeper.SetToDistribute(ctx, amt, k.GetAuthority()); err != nil { // TODO: this should be distribution module account + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.ProtocolPoolDistrAccount, amt); err != nil { return err } @@ -170,7 +165,7 @@ func (k Keeper) sendDecimalPoolToCommunityPool(ctx context.Context) error { } amt, re := feePool.DecimalPool.TruncateDecimal() - if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.ProtocolPoolModuleName, amt); err != nil { + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.ProtocolPoolDistrAccount, amt); err != nil { return err } diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index b76b3409fbc..f319ad456cb 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -51,7 +51,6 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) env := runtime.NewEnvironment(runtime.NewKVStoreService(key), coretesting.NewNopLogger()) @@ -69,7 +68,6 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -118,7 +116,6 @@ func TestAllocateTokensToManyValidators(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) feeCollectorAcc := authtypes.NewEmptyModuleAccount("fee_collector") accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) @@ -136,7 +133,6 @@ func TestAllocateTokensToManyValidators(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -200,8 +196,7 @@ func TestAllocateTokensToManyValidators(t *testing.T) { fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) bankKeeper.EXPECT().GetAllBalances(gomock.Any(), feeCollectorAcc.GetAddress()).Return(fees) bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), "fee_collector", disttypes.ModuleName, fees) - bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), disttypes.ModuleName, disttypes.ProtocolPoolModuleName, sdk.Coins{{Denom: sdk.DefaultBondDenom, Amount: math.NewInt(2)}}) // 2 community pool coins - poolKeeper.EXPECT().SetToDistribute(ctx, gomock.Any(), gomock.Any()) + bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), disttypes.ModuleName, disttypes.ProtocolPoolDistrAccount, sdk.Coins{{Denom: sdk.DefaultBondDenom, Amount: math.NewInt(2)}}) // 2 community pool coins votes := []comet.VoteInfo{ { @@ -259,7 +254,6 @@ func TestAllocateTokensTruncation(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) feeCollectorAcc := authtypes.NewEmptyModuleAccount("fee_collector") accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) @@ -277,7 +271,6 @@ func TestAllocateTokensTruncation(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -354,8 +347,7 @@ func TestAllocateTokensTruncation(t *testing.T) { fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(634195840))) bankKeeper.EXPECT().GetAllBalances(gomock.Any(), feeCollectorAcc.GetAddress()).Return(fees) bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), "fee_collector", disttypes.ModuleName, fees) - bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), disttypes.ModuleName, disttypes.ProtocolPoolModuleName, gomock.Any()) // something is sent to community pool - poolKeeper.EXPECT().SetToDistribute(ctx, gomock.Any(), gomock.Any()) + bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), disttypes.ModuleName, disttypes.ProtocolPoolDistrAccount, gomock.Any()) // something is sent to community pool votes := []comet.VoteInfo{ { diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index 76bcfb62878..31419b10e08 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -36,7 +36,6 @@ func TestCalculateRewardsBasic(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -53,7 +52,6 @@ func TestCalculateRewardsBasic(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -150,7 +148,6 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -167,7 +164,6 @@ func TestCalculateRewardsAfterSlash(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -267,7 +263,6 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -284,7 +279,6 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -405,7 +399,6 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -422,7 +415,6 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -516,7 +508,6 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -533,7 +524,6 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -605,7 +595,6 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -622,7 +611,6 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -735,7 +723,6 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -752,7 +739,6 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -889,7 +875,6 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -906,7 +891,6 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -1103,7 +1087,6 @@ func Test100PercentCommissionReward(t *testing.T) { bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec(sdk.Bech32PrefixValAddr)).AnyTimes() @@ -1121,7 +1104,6 @@ func Test100PercentCommissionReward(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, diff --git a/x/distribution/keeper/grpc_query.go b/x/distribution/keeper/grpc_query.go index 62b602c8a80..de8657276fb 100644 --- a/x/distribution/keeper/grpc_query.go +++ b/x/distribution/keeper/grpc_query.go @@ -373,9 +373,12 @@ func (k Querier) DelegatorWithdrawAddress(ctx context.Context, req *types.QueryD // This method uses deprecated query request. Use CommunityPool from x/protocolpool module instead. // CommunityPool queries the community pool coins func (k Querier) CommunityPool(ctx context.Context, req *types.QueryCommunityPoolRequest) (*types.QueryCommunityPoolResponse, error) { - pool, err := k.poolKeeper.GetCommunityPool(ctx) - if err != nil { - return nil, err + moduleAccount := k.authKeeper.GetModuleAccount(ctx, types.ProtocolPoolModuleName) + if moduleAccount == nil { + return nil, status.Error(codes.Internal, "protocolpool module account does not exist") } - return &types.QueryCommunityPoolResponse{Pool: sdk.NewDecCoinsFromCoins(pool...)}, nil + + balances := k.bankKeeper.GetAllBalances(ctx, moduleAccount.GetAddress()) + + return &types.QueryCommunityPoolResponse{Pool: sdk.NewDecCoinsFromCoins(balances...)}, nil } diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index 14bbbd66902..affc16b392b 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" "cosmossdk.io/math" + authtypes "cosmossdk.io/x/auth/types" "cosmossdk.io/x/distribution/keeper" distrtestutil "cosmossdk.io/x/distribution/testutil" "cosmossdk.io/x/distribution/types" @@ -147,9 +148,13 @@ func TestQueryCommunityPool(t *testing.T) { ctx, _, distrKeeper, dep := initFixture(t) queryServer := keeper.NewQuerier(distrKeeper) + poolAcc := authtypes.NewEmptyModuleAccount(types.ProtocolPoolModuleName) + dep.accountKeeper.EXPECT().GetModuleAccount(gomock.Any(), types.ProtocolPoolModuleName).Return(poolAcc).AnyTimes() + + dep.bankKeeper.EXPECT().GetAllBalances(gomock.Any(), poolAcc.GetAddress()).Return(sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100)))) + coins := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))) decCoins := sdk.NewDecCoinsFromCoins(coins...) - dep.poolKeeper.EXPECT().GetCommunityPool(gomock.Any()).Return(coins, nil).AnyTimes() cases := []struct { name string diff --git a/x/distribution/keeper/keeper.go b/x/distribution/keeper/keeper.go index bc5096c4c50..0c3238353eb 100644 --- a/x/distribution/keeper/keeper.go +++ b/x/distribution/keeper/keeper.go @@ -28,7 +28,6 @@ type Keeper struct { authKeeper types.AccountKeeper bankKeeper types.BankKeeper stakingKeeper types.StakingKeeper - poolKeeper types.PoolKeeper // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. @@ -64,7 +63,6 @@ func NewKeeper( ak types.AccountKeeper, bk types.BankKeeper, sk types.StakingKeeper, - pk types.PoolKeeper, cometService comet.Service, feeCollectorName, authority string, ) Keeper { @@ -81,7 +79,6 @@ func NewKeeper( authKeeper: ak, bankKeeper: bk, stakingKeeper: sk, - poolKeeper: pk, feeCollectorName: feeCollectorName, authority: authority, Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index 8b6afcebd9c..a3fdb44d797 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -30,7 +30,6 @@ type dep struct { bankKeeper *distrtestutil.MockBankKeeper stakingKeeper *distrtestutil.MockStakingKeeper accountKeeper *distrtestutil.MockAccountKeeper - poolKeeper *distrtestutil.MockPoolKeeper } func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, dep) { @@ -47,7 +46,6 @@ func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, de bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() @@ -69,7 +67,6 @@ func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, de accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, testCometService, "fee_collector", authorityAddr, @@ -78,7 +75,7 @@ func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, de params := types.DefaultParams() require.NoError(t, distrKeeper.Params.Set(ctx, params)) - return ctx, addrs, distrKeeper, dep{bankKeeper, stakingKeeper, accountKeeper, poolKeeper} + return ctx, addrs, distrKeeper, dep{bankKeeper, stakingKeeper, accountKeeper} } func TestSetWithdrawAddr(t *testing.T) { diff --git a/x/distribution/keeper/migrations.go b/x/distribution/keeper/migrations.go index cb6be65cb6b..7a35fa76f89 100644 --- a/x/distribution/keeper/migrations.go +++ b/x/distribution/keeper/migrations.go @@ -42,7 +42,7 @@ func (m Migrator) Migrate3to4(ctx context.Context) error { func (m Migrator) migrateFunds(ctx context.Context) error { macc := m.keeper.GetDistributionAccount(ctx) - poolMacc := m.keeper.authKeeper.GetModuleAccount(ctx, types.ProtocolPoolModuleName) + poolMacc := m.keeper.authKeeper.GetModuleAccount(ctx, types.ProtocolPoolDistrAccount) feePool, err := m.keeper.FeePool.Get(ctx) if err != nil { diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index 6f8b622f52b..2b405f9b053 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -114,7 +114,7 @@ func (k msgServer) FundCommunityPool(ctx context.Context, msg *types.MsgFundComm return nil, err } - if err := k.poolKeeper.FundCommunityPool(ctx, msg.Amount, depositor); err != nil { + if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ProtocolPoolModuleName, msg.Amount); err != nil { return nil, err } @@ -158,7 +158,7 @@ func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommuni return nil, fmt.Errorf("invalid recipient address: %w", err) } - if err := k.poolKeeper.DistributeFromCommunityPool(ctx, msg.Amount, recipient); err != nil { + if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ProtocolPoolModuleName, recipient, msg.Amount); err != nil { return nil, err } diff --git a/x/distribution/keeper/msg_server_test.go b/x/distribution/keeper/msg_server_test.go index 8c5cad6d39a..59a21395de4 100644 --- a/x/distribution/keeper/msg_server_test.go +++ b/x/distribution/keeper/msg_server_test.go @@ -176,12 +176,13 @@ func TestMsgWithdrawValidatorCommission(t *testing.T) { func TestMsgFundCommunityPool(t *testing.T) { ctx, addrs, distrKeeper, dep := initFixture(t) - dep.poolKeeper.EXPECT().FundCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() msgServer := keeper.NewMsgServerImpl(distrKeeper) addr0Str, err := codectestutil.CodecOptions{}.GetAddressCodec().BytesToString(addrs[0]) require.NoError(t, err) + dep.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), addrs[0], types.ProtocolPoolModuleName, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000)))).Return(nil) + cases := []struct { name string msg *types.MsgFundCommunityPool //nolint:staticcheck // Testing deprecated method @@ -281,7 +282,6 @@ func TestMsgUpdateParams(t *testing.T) { func TestMsgCommunityPoolSpend(t *testing.T) { ctx, addrs, distrKeeper, dep := initFixture(t) - dep.poolKeeper.EXPECT().DistributeFromCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() msgServer := keeper.NewMsgServerImpl(distrKeeper) authorityAddr, err := codectestutil.CodecOptions{}.GetAddressCodec().BytesToString(authtypes.NewModuleAddress("gov")) @@ -289,6 +289,8 @@ func TestMsgCommunityPoolSpend(t *testing.T) { addr0Str, err := codectestutil.CodecOptions{}.GetAddressCodec().BytesToString(addrs[0]) require.NoError(t, err) + dep.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), types.ProtocolPoolModuleName, addrs[0], sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000)))).Return(nil) + cases := []struct { name string msg *types.MsgCommunityPoolSpend //nolint:staticcheck // Testing deprecated method diff --git a/x/distribution/migrations/v4/migrate_funds_test.go b/x/distribution/migrations/v4/migrate_funds_test.go index e801040009a..90f557e130c 100644 --- a/x/distribution/migrations/v4/migrate_funds_test.go +++ b/x/distribution/migrations/v4/migrate_funds_test.go @@ -60,7 +60,6 @@ func TestFundsMigration(t *testing.T) { ctrl := gomock.NewController(t) acctsModKeeper := authtestutil.NewMockAccountsModKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accNum := uint64(0) acctsModKeeper.EXPECT().NextAccountNumber(gomock.Any()).AnyTimes().DoAndReturn(func(ctx context.Context) (uint64, error) { @@ -97,7 +96,6 @@ func TestFundsMigration(t *testing.T) { accountKeeper, bankKeeper, stakingKeeper, - poolKeeper, &emptyCometService{}, disttypes.ModuleName, authority, diff --git a/x/distribution/module.go b/x/distribution/module.go index bd0d3c6d3c8..82e99106933 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -48,13 +48,12 @@ type AppModule struct { accountKeeper types.AccountKeeper bankKeeper types.BankKeeper stakingKeeper types.StakingKeeper - poolKeeper types.PoolKeeper } // NewAppModule creates a new AppModule object func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, stakingKeeper types.StakingKeeper, poolKeeper types.PoolKeeper, + bankKeeper types.BankKeeper, stakingKeeper types.StakingKeeper, ) AppModule { return AppModule{ cdc: cdc, @@ -62,7 +61,6 @@ func NewAppModule( accountKeeper: accountKeeper, bankKeeper: bankKeeper, stakingKeeper: stakingKeeper, - poolKeeper: poolKeeper, } } diff --git a/x/distribution/testutil/expected_keepers_mocks.go b/x/distribution/testutil/expected_keepers_mocks.go index a2a2d669f86..e30590d865e 100644 --- a/x/distribution/testutil/expected_keepers_mocks.go +++ b/x/distribution/testutil/expected_keepers_mocks.go @@ -240,86 +240,6 @@ func (mr *MockBankKeeperMockRecorder) SpendableCoins(ctx, addr interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableCoins", reflect.TypeOf((*MockBankKeeper)(nil).SpendableCoins), ctx, addr) } -// MockPoolKeeper is a mock of PoolKeeper interface. -type MockPoolKeeper struct { - ctrl *gomock.Controller - recorder *MockPoolKeeperMockRecorder -} - -// MockPoolKeeperMockRecorder is the mock recorder for MockPoolKeeper. -type MockPoolKeeperMockRecorder struct { - mock *MockPoolKeeper -} - -// NewMockPoolKeeper creates a new mock instance. -func NewMockPoolKeeper(ctrl *gomock.Controller) *MockPoolKeeper { - mock := &MockPoolKeeper{ctrl: ctrl} - mock.recorder = &MockPoolKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockPoolKeeper) EXPECT() *MockPoolKeeperMockRecorder { - return m.recorder -} - -// DistributeFromCommunityPool mocks base method. -func (m *MockPoolKeeper) DistributeFromCommunityPool(ctx context.Context, amount types0.Coins, receiveAddr types0.AccAddress) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DistributeFromCommunityPool", ctx, amount, receiveAddr) - ret0, _ := ret[0].(error) - return ret0 -} - -// DistributeFromCommunityPool indicates an expected call of DistributeFromCommunityPool. -func (mr *MockPoolKeeperMockRecorder) DistributeFromCommunityPool(ctx, amount, receiveAddr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DistributeFromCommunityPool", reflect.TypeOf((*MockPoolKeeper)(nil).DistributeFromCommunityPool), ctx, amount, receiveAddr) -} - -// FundCommunityPool mocks base method. -func (m *MockPoolKeeper) FundCommunityPool(ctx context.Context, amount types0.Coins, sender types0.AccAddress) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) - ret0, _ := ret[0].(error) - return ret0 -} - -// FundCommunityPool indicates an expected call of FundCommunityPool. -func (mr *MockPoolKeeperMockRecorder) FundCommunityPool(ctx, amount, sender interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FundCommunityPool", reflect.TypeOf((*MockPoolKeeper)(nil).FundCommunityPool), ctx, amount, sender) -} - -// GetCommunityPool mocks base method. -func (m *MockPoolKeeper) GetCommunityPool(ctx context.Context) (types0.Coins, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCommunityPool", ctx) - ret0, _ := ret[0].(types0.Coins) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCommunityPool indicates an expected call of GetCommunityPool. -func (mr *MockPoolKeeperMockRecorder) GetCommunityPool(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommunityPool", reflect.TypeOf((*MockPoolKeeper)(nil).GetCommunityPool), ctx) -} - -// SetToDistribute mocks base method. -func (m *MockPoolKeeper) SetToDistribute(ctx context.Context, amount types0.Coins, addr string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetToDistribute", ctx, amount, addr) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetToDistribute indicates an expected call of SetToDistribute. -func (mr *MockPoolKeeperMockRecorder) SetToDistribute(ctx, amount, addr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetToDistribute", reflect.TypeOf((*MockPoolKeeper)(nil).SetToDistribute), ctx, amount, addr) -} - // MockStakingKeeper is a mock of StakingKeeper interface. type MockStakingKeeper struct { ctrl *gomock.Controller diff --git a/x/distribution/types/expected_keepers.go b/x/distribution/types/expected_keepers.go index e0fa03dbb1e..8288f220628 100644 --- a/x/distribution/types/expected_keepers.go +++ b/x/distribution/types/expected_keepers.go @@ -34,14 +34,6 @@ type BankKeeper interface { IsSendEnabledDenom(ctx context.Context, denom string) bool } -// PoolKeeper defines the expected interface needed to fund & distribute pool balances. -type PoolKeeper interface { - FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error - DistributeFromCommunityPool(ctx context.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error - GetCommunityPool(ctx context.Context) (sdk.Coins, error) - SetToDistribute(ctx context.Context, amount sdk.Coins, addr string) error -} - // StakingKeeper expected staking keeper (noalias) type StakingKeeper interface { ValidatorAddressCodec() address.Codec diff --git a/x/distribution/types/keys.go b/x/distribution/types/keys.go index e4409d9d595..cee527708b8 100644 --- a/x/distribution/types/keys.go +++ b/x/distribution/types/keys.go @@ -24,7 +24,12 @@ const ( // It should be synced with the gov module's name if it is ever changed. // See: https://github.com/cosmos/cosmos-sdk/blob/b62a28aac041829da5ded4aeacfcd7a42873d1c8/x/gov/types/keys.go#L9 GovModuleName = "gov" - // ProtocolPoolModuleName duplicates the protocolpool module's name to avoid a cyclic dependency with x/protocolpool. + // ProtocolPoolDistrAccount duplicates the protocolpool_distr accounts's name to avoid a cyclic dependency with x/protocolpool. + // This account is an intermediary account that holds the funds to be distributed to the protocolpool accounts. + ProtocolPoolDistrAccount = "protocolpool_distr" + + // ProtocolPoolModuleName duplicates the protocolpool accounts's name to avoid a cyclic dependency with x/protocolpool. + // DO NOT USE: This is only used in deprecated methods CommunityPoolSpend, FundCommunityPool and query CommunityPool. ProtocolPoolModuleName = "protocolpool" ) diff --git a/x/gov/testutil/expected_keepers.go b/x/gov/testutil/expected_keepers.go index 987a7a895eb..9da4b715663 100644 --- a/x/gov/testutil/expected_keepers.go +++ b/x/gov/testutil/expected_keepers.go @@ -43,7 +43,7 @@ type BankKeeper interface { // PoolKeeper extends the gov's actual expected PoolKeeper. type PoolKeeper interface { - FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error + FundCommunityPool(ctx context.Context, amount sdk.Coins, sender []byte) error } // StakingKeeper extends gov's actual expected StakingKeeper with additional diff --git a/x/gov/testutil/expected_keepers_mocks.go b/x/gov/testutil/expected_keepers_mocks.go index ea9e9e535bc..4636f53df68 100644 --- a/x/gov/testutil/expected_keepers_mocks.go +++ b/x/gov/testutil/expected_keepers_mocks.go @@ -290,7 +290,7 @@ func (m *MockPoolKeeper) EXPECT() *MockPoolKeeperMockRecorder { } // FundCommunityPool mocks base method. -func (m *MockPoolKeeper) FundCommunityPool(ctx context.Context, amount types.Coins, sender types.AccAddress) error { +func (m *MockPoolKeeper) FundCommunityPool(ctx context.Context, amount types.Coins, sender []byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) ret0, _ := ret[0].(error) diff --git a/x/gov/types/expected_keepers.go b/x/gov/types/expected_keepers.go index 31d19af74d6..7a14d90dbe6 100644 --- a/x/gov/types/expected_keepers.go +++ b/x/gov/types/expected_keepers.go @@ -51,7 +51,7 @@ type BankKeeper interface { // PoolKeeper defines the expected interface needed to fund & distribute pool balances. type PoolKeeper interface { - FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error + FundCommunityPool(ctx context.Context, amount sdk.Coins, sender []byte) error } // Event Hooks diff --git a/x/protocolpool/CHANGELOG.md b/x/protocolpool/CHANGELOG.md new file mode 100644 index 00000000000..71b68611819 --- /dev/null +++ b/x/protocolpool/CHANGELOG.md @@ -0,0 +1,30 @@ + + +# Changelog + +## [Unreleased] + +### Improvements + +* [#20790](https://github.com/cosmos/cosmos-sdk/pull/20790) `x/protocolpool` now has its own BeginBlock. diff --git a/x/protocolpool/keeper/genesis.go b/x/protocolpool/keeper/genesis.go index b7da5a204bc..fa32a08f9a5 100644 --- a/x/protocolpool/keeper/genesis.go +++ b/x/protocolpool/keeper/genesis.go @@ -3,7 +3,9 @@ package keeper import ( "context" "fmt" + "time" + "cosmossdk.io/math" "cosmossdk.io/x/protocolpool/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -49,8 +51,21 @@ func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error } } - if err := k.ToDistribute.Set(ctx, data.ToDistribute); err != nil { - return fmt.Errorf("failed to set to distribute: %w", err) + if err := k.LastBalance.Set(ctx, data.LastBalance); err != nil { + return fmt.Errorf("failed to set last balance: %w", err) + } + + totalToBeDistributed := math.ZeroInt() + for _, distribution := range data.Distributions { + totalToBeDistributed = totalToBeDistributed.Add(distribution.Amount) + if err := k.Distributions.Set(ctx, *distribution.Time, distribution.Amount); err != nil { + return fmt.Errorf("failed to set distribution: %w", err) + } + } + + // sanity check to avoid trying to distribute more than what is available + if data.LastBalance.LT(totalToBeDistributed) { + return fmt.Errorf("total to be distributed is greater than the last balance") } return nil @@ -96,7 +111,19 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) genState := types.NewGenesisState(cf, budget) - genState.ToDistribute, err = k.ToDistribute.Get(ctx) + genState.LastBalance, err = k.LastBalance.Get(ctx) + if err != nil { + return nil, err + } + + err = k.Distributions.Walk(ctx, nil, func(key time.Time, value math.Int) (stop bool, err error) { + genState.Distributions = append(genState.Distributions, &types.Distribution{ + Time: &key, + Amount: value, + }) + + return false, nil + }) if err != nil { return nil, err } diff --git a/x/protocolpool/keeper/genesis_test.go b/x/protocolpool/keeper/genesis_test.go index 4653ff61630..f0149f66278 100644 --- a/x/protocolpool/keeper/genesis_test.go +++ b/x/protocolpool/keeper/genesis_test.go @@ -31,7 +31,17 @@ func (suite *KeeperTestSuite) TestInitGenesis() { }, ) + gs.Distributions = append(gs.Distributions, &types.Distribution{ + Amount: math.OneInt(), + Time: &time.Time{}, + }) + err := suite.poolKeeper.InitGenesis(suite.ctx, gs) + suite.Require().ErrorContains(err, "total to be distributed is greater than the last balance") + + // Set last balance + gs.LastBalance = math.NewInt(1) + err = suite.poolKeeper.InitGenesis(suite.ctx, gs) suite.Require().NoError(err) // Export @@ -39,4 +49,5 @@ func (suite *KeeperTestSuite) TestInitGenesis() { suite.Require().NoError(err) suite.Require().Equal(gs.ContinuousFund, exportedGenState.ContinuousFund) suite.Require().Equal(gs.Budget, exportedGenState.Budget) + suite.Require().Equal(math.OneInt(), exportedGenState.LastBalance) } diff --git a/x/protocolpool/keeper/keeper.go b/x/protocolpool/keeper/keeper.go index 038fd3260d8..f74b10af986 100644 --- a/x/protocolpool/keeper/keeper.go +++ b/x/protocolpool/keeper/keeper.go @@ -1,10 +1,10 @@ package keeper import ( - "bytes" "context" "errors" "fmt" + "sort" "time" "cosmossdk.io/collections" @@ -35,8 +35,8 @@ type Keeper struct { ContinuousFund collections.Map[sdk.AccAddress, types.ContinuousFund] // RecipientFundDistribution key: RecipientAddr | value: Claimable amount RecipientFundDistribution collections.Map[sdk.AccAddress, math.Int] - // ToDistribute is to keep track of funds to be distributed. It gets zeroed out in iterateAndUpdateFundsDistribution. - ToDistribute collections.Item[math.Int] + Distributions collections.Map[time.Time, math.Int] // key: time.Time | value: amount + LastBalance collections.Item[math.Int] } func NewKeeper(cdc codec.BinaryCodec, env appmodule.Environment, ak types.AccountKeeper, bk types.BankKeeper, sk types.StakingKeeper, authority string, @@ -49,6 +49,10 @@ func NewKeeper(cdc codec.BinaryCodec, env appmodule.Environment, ak types.Accoun if addr := ak.GetModuleAddress(types.StreamAccount); addr == nil { panic(fmt.Sprintf("%s module account has not been set", types.StreamAccount)) } + // ensure protocol pool distribution account is set + if addr := ak.GetModuleAddress(types.ProtocolPoolDistrAccount); addr == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ProtocolPoolDistrAccount)) + } sb := collections.NewSchemaBuilder(env.KVStoreService) @@ -62,7 +66,8 @@ func NewKeeper(cdc codec.BinaryCodec, env appmodule.Environment, ak types.Accoun BudgetProposal: collections.NewMap(sb, types.BudgetKey, "budget", sdk.AccAddressKey, codec.CollValue[types.Budget](cdc)), ContinuousFund: collections.NewMap(sb, types.ContinuousFundKey, "continuous_fund", sdk.AccAddressKey, codec.CollValue[types.ContinuousFund](cdc)), RecipientFundDistribution: collections.NewMap(sb, types.RecipientFundDistributionKey, "recipient_fund_distribution", sdk.AccAddressKey, sdk.IntValue), - ToDistribute: collections.NewItem(sb, types.ToDistributeKey, "to_distribute", sdk.IntValue), + Distributions: collections.NewMap(sb, types.DistributionsKey, "distributions", sdk.TimeKey, sdk.IntValue), + LastBalance: collections.NewItem(sb, types.LastBalanceKey, "last_balance", sdk.IntValue), } schema, err := sb.Build() @@ -80,19 +85,19 @@ func (k Keeper) GetAuthority() string { } // FundCommunityPool allows an account to directly fund the community fund pool. -func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error { +func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender []byte) error { return k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount) } // DistributeFromCommunityPool distributes funds from the protocolpool module account to // a receiver address. -func (k Keeper) DistributeFromCommunityPool(ctx context.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { +func (k Keeper) DistributeFromCommunityPool(ctx context.Context, amount sdk.Coins, receiveAddr []byte) error { return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) } // DistributeFromStreamFunds distributes funds from the protocolpool's stream module account to // a receiver address. -func (k Keeper) DistributeFromStreamFunds(ctx context.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { +func (k Keeper) DistributeFromStreamFunds(ctx context.Context, amount sdk.Coins, receiveAddr []byte) error { return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.StreamAccount, receiveAddr, amount) } @@ -100,48 +105,17 @@ func (k Keeper) DistributeFromStreamFunds(ctx context.Context, amount sdk.Coins, func (k Keeper) GetCommunityPool(ctx context.Context) (sdk.Coins, error) { moduleAccount := k.authKeeper.GetModuleAccount(ctx, types.ModuleName) if moduleAccount == nil { - return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleAccount) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", types.ModuleName) } return k.bankKeeper.GetAllBalances(ctx, moduleAccount.GetAddress()), nil } -func (k Keeper) withdrawContinuousFund(ctx context.Context, recipientAddr string) (sdk.Coin, error) { - recipient, err := k.authKeeper.AddressCodec().StringToBytes(recipientAddr) - if err != nil { - return sdk.Coin{}, sdkerrors.ErrInvalidAddress.Wrapf("invalid recipient address: %s", err) - } - - cf, err := k.ContinuousFund.Get(ctx, recipient) - if err != nil { - if errors.Is(err, collections.ErrNotFound) { - return sdk.Coin{}, fmt.Errorf("no continuous fund found for recipient: %s", recipientAddr) - } - return sdk.Coin{}, fmt.Errorf("get continuous fund failed for recipient: %s", recipientAddr) - } - if cf.Expiry != nil && cf.Expiry.Before(k.HeaderService.HeaderInfo(ctx).Time) { - return sdk.Coin{}, fmt.Errorf("cannot withdraw continuous funds: continuous fund expired for recipient: %s", recipientAddr) - } - - err = k.IterateAndUpdateFundsDistribution(ctx) - if err != nil { - return sdk.Coin{}, fmt.Errorf("error while iterating all the continuous funds: %w", err) - } - - // withdraw continuous fund - withdrawnAmount, err := k.withdrawRecipientFunds(ctx, recipient) - if err != nil { - return sdk.Coin{}, fmt.Errorf("error while withdrawing recipient funds for recipient: %s", recipientAddr) - } - - return withdrawnAmount, nil -} - func (k Keeper) withdrawRecipientFunds(ctx context.Context, recipient []byte) (sdk.Coin, error) { // get allocated continuous fund fundsAllocated, err := k.RecipientFundDistribution.Get(ctx, recipient) if err != nil { if errors.Is(err, collections.ErrNotFound) { - return sdk.Coin{}, types.ErrNoRecipientFund + return sdk.Coin{}, types.ErrNoRecipientFound } return sdk.Coin{}, err } @@ -166,20 +140,12 @@ func (k Keeper) withdrawRecipientFunds(ctx context.Context, recipient []byte) (s return withdrawnAmount, nil } -// SetToDistribute sets the amount to be distributed among recipients, usually called by x/distribution while allocating -// reward and fee distribution. -// This could be only set by the authority address. -func (k Keeper) SetToDistribute(ctx context.Context, amount sdk.Coins, addr string) error { - authAddr, err := k.authKeeper.AddressCodec().StringToBytes(addr) - if err != nil { - return err - } - hasPermission, err := k.hasPermission(authAddr) - if err != nil { - return err - } - if !hasPermission { - return sdkerrors.ErrUnauthorized +// SetToDistribute sets the amount to be distributed among recipients. +func (k Keeper) SetToDistribute(ctx context.Context) error { + // Get current balance of the intermediary module account + moduleAccount := k.authKeeper.GetModuleAccount(ctx, types.ProtocolPoolDistrAccount) + if moduleAccount == nil { + return errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", types.ProtocolPoolDistrAccount) } denom, err := k.stakingKeeper.BondDenom(ctx) @@ -187,116 +153,154 @@ func (k Keeper) SetToDistribute(ctx context.Context, amount sdk.Coins, addr stri return err } - totalStreamFundsPercentage := math.LegacyZeroDec() - err = k.ContinuousFund.Walk(ctx, nil, func(key sdk.AccAddress, cf types.ContinuousFund) (stop bool, err error) { - // Check if the continuous fund has expired - if cf.Expiry != nil && cf.Expiry.Before(k.HeaderService.HeaderInfo(ctx).Time) { - return false, nil - } - - totalStreamFundsPercentage = totalStreamFundsPercentage.Add(cf.Percentage) - if totalStreamFundsPercentage.GT(math.LegacyOneDec()) { - return true, errors.New("total funds percentage cannot exceed 100") - } - - return false, nil - }) - if err != nil { - return err - } + currentBalance := k.bankKeeper.GetAllBalances(ctx, moduleAccount.GetAddress()) + distributionBalance := currentBalance.AmountOf(denom) - // if percentage is 0 then return early - if totalStreamFundsPercentage.IsZero() { + // if the balance is zero, return early + if distributionBalance.IsZero() { return nil } - // send streaming funds to the stream module account - toDistributeAmt := math.LegacyNewDecFromInt(amount.AmountOf(denom)).Mul(totalStreamFundsPercentage).TruncateInt() - streamAmt := sdk.NewCoins(sdk.NewCoin(denom, toDistributeAmt)) - if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.StreamAccount, streamAmt); err != nil { - return err - } - - amountToDistribute, err := k.ToDistribute.Get(ctx) + lastBalance, err := k.LastBalance.Get(ctx) if err != nil { if errors.Is(err, collections.ErrNotFound) { - amountToDistribute = math.ZeroInt() + lastBalance = math.ZeroInt() } else { return err } } - err = k.ToDistribute.Set(ctx, amountToDistribute.Add(amount.AmountOf(denom))) - if err != nil { - return fmt.Errorf("error while setting ToDistribute: %w", err) - } - return nil -} + // Calculate the amount to be distributed + amountToDistribute := distributionBalance.Sub(lastBalance) -func (k Keeper) hasPermission(addr []byte) (bool, error) { - authority := k.GetAuthority() - authAcc, err := k.authKeeper.AddressCodec().StringToBytes(authority) - if err != nil { - return false, err + if err = k.Distributions.Set(ctx, k.HeaderService.HeaderInfo(ctx).Time, amountToDistribute); err != nil { + return fmt.Errorf("error while setting Distributions: %w", err) } - return bytes.Equal(authAcc, addr), nil + // Update the last balance + return k.LastBalance.Set(ctx, distributionBalance) } func (k Keeper) IterateAndUpdateFundsDistribution(ctx context.Context) error { - toDistributeAmount, err := k.ToDistribute.Get(ctx) + // first we get all the continuous funds, and keep a list of the ones that expired so we can delete later + funds := []types.ContinuousFund{} + toDelete := [][]byte{} + err := k.ContinuousFund.Walk(ctx, nil, func(key sdk.AccAddress, cf types.ContinuousFund) (stop bool, err error) { + funds = append(funds, cf) + + // check if the continuous fund has expired, and add it to the list of funds to delete + if cf.Expiry != nil && cf.Expiry.Before(k.HeaderService.HeaderInfo(ctx).Time) { + toDelete = append(toDelete, key) + } + + return false, nil + }) if err != nil { return err } - // if there are no funds to distribute, return - if toDistributeAmount.IsZero() { - return nil + // next we iterate over the distributions, calculate each recipient's share and the remaining pool funds + toDistribute := map[string]math.Int{} + poolFunds := math.ZeroInt() + fullAmountToDistribute := math.ZeroInt() + + if err = k.Distributions.Walk(ctx, nil, func(key time.Time, amount math.Int) (stop bool, err error) { + percentageToDistribute := math.LegacyZeroDec() + for _, f := range funds { + if f.Expiry != nil && f.Expiry.Before(key) { + continue + } + + percentageToDistribute = percentageToDistribute.Add(f.Percentage) + + _, ok := toDistribute[f.Recipient] + if !ok { + toDistribute[f.Recipient] = math.ZeroInt() + } + amountToDistribute := f.Percentage.MulInt(amount).TruncateInt() + toDistribute[f.Recipient] = toDistribute[f.Recipient].Add(amountToDistribute) + fullAmountToDistribute = fullAmountToDistribute.Add(amountToDistribute) + } + + // sanity check for max percentage + if percentageToDistribute.GT(math.LegacyOneDec()) { + return true, errors.New("total funds percentage cannot exceed 100") + } + + remaining := math.LegacyOneDec().Sub(percentageToDistribute).MulInt(amount).RoundInt() + poolFunds = poolFunds.Add(remaining) + + return false, nil + }); err != nil { + return err } - totalPercentageToBeDistributed := math.LegacyZeroDec() + // clear the distributions and reset the last balance + if err = k.Distributions.Clear(ctx, nil); err != nil { + return err + } - denom, err := k.stakingKeeper.BondDenom(ctx) + if err = k.LastBalance.Set(ctx, math.ZeroInt()); err != nil { + return err + } + + // send the funds to the stream account to be distributed later, and the remaining to the community pool + bondDenom, err := k.stakingKeeper.BondDenom(ctx) if err != nil { return err } - toDistributeDec := sdk.NewDecCoin(denom, toDistributeAmount) - // Calculate totalPercentageToBeDistributed and store values - err = k.ContinuousFund.Walk(ctx, nil, func(key sdk.AccAddress, cf types.ContinuousFund) (stop bool, err error) { - // Check if the continuous fund has expired - if cf.Expiry != nil && cf.Expiry.Before(k.HeaderService.HeaderInfo(ctx).Time) { - return false, nil + streamAmt := sdk.NewCoins(sdk.NewCoin(bondDenom, fullAmountToDistribute)) + if !streamAmt.IsZero() { + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ProtocolPoolDistrAccount, types.StreamAccount, streamAmt); err != nil { + return err } + } - // sanity check for max percentage - totalPercentageToBeDistributed = totalPercentageToBeDistributed.Add(cf.Percentage) - if totalPercentageToBeDistributed.GT(math.LegacyOneDec()) { - return true, errors.New("total funds percentage cannot exceed 100") + if !poolFunds.IsZero() { + poolCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, poolFunds)) + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ProtocolPoolDistrAccount, types.ModuleName, poolCoins); err != nil { + return err } + } - // Calculate the funds to be distributed based on the percentage - recipientAmount := toDistributeDec.Amount.Mul(cf.Percentage).TruncateInt() + // update the recipient fund distribution, first get the keys and sort them + recipients := make([]string, 0, len(toDistribute)) + for k2 := range toDistribute { + recipients = append(recipients, k2) + } + sort.Strings(recipients) + for _, recipient := range recipients { // Set funds to be claimed - toClaim, err := k.RecipientFundDistribution.Get(ctx, key) + bzAddr, err := k.authKeeper.AddressCodec().StringToBytes(recipient) if err != nil { - return true, err + return err } - amount := toClaim.Add(recipientAmount) - err = k.RecipientFundDistribution.Set(ctx, key, amount) + + toClaim, err := k.RecipientFundDistribution.Get(ctx, bzAddr) if err != nil { - return true, err + if errors.Is(err, collections.ErrNotFound) { + toClaim = math.ZeroInt() + } else { + return err + } } - return false, nil - }) - if err != nil { - return err + amount := toClaim.Add(toDistribute[recipient]) + if err = k.RecipientFundDistribution.Set(ctx, bzAddr, amount); err != nil { + return err + } + } + + // delete expired continuous funds + for _, recipient := range toDelete { + if err = k.ContinuousFund.Remove(ctx, recipient); err != nil { + return err + } } - // Set the coins to be distributed from toDistribute to 0 - return k.ToDistribute.Set(ctx, math.ZeroInt()) + return nil } func (k Keeper) claimFunds(ctx context.Context, recipientAddr string) (amount sdk.Coin, err error) { @@ -472,3 +476,7 @@ func (k Keeper) validateContinuousFund(ctx context.Context, msg types.MsgCreateC return nil } + +func (k Keeper) BeginBlocker(ctx context.Context) error { + return k.SetToDistribute(ctx) +} diff --git a/x/protocolpool/keeper/keeper_test.go b/x/protocolpool/keeper/keeper_test.go index ddfcd6d8241..1f5b1f1bce0 100644 --- a/x/protocolpool/keeper/keeper_test.go +++ b/x/protocolpool/keeper/keeper_test.go @@ -27,8 +27,9 @@ import ( ) var ( - poolAcc = authtypes.NewEmptyModuleAccount(types.ModuleName) - streamAcc = authtypes.NewEmptyModuleAccount(types.StreamAccount) + poolAcc = authtypes.NewEmptyModuleAccount(types.ModuleName) + streamAcc = authtypes.NewEmptyModuleAccount(types.StreamAccount) + poolDistrAcc = authtypes.NewEmptyModuleAccount(types.ProtocolPoolDistrAccount) ) type KeeperTestSuite struct { @@ -57,6 +58,7 @@ func (s *KeeperTestSuite) SetupTest() { ctrl := gomock.NewController(s.T()) accountKeeper := pooltestutil.NewMockAccountKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress(types.ModuleName).Return(poolAcc.GetAddress()) + accountKeeper.EXPECT().GetModuleAddress(types.ProtocolPoolDistrAccount).Return(poolDistrAcc.GetAddress()) accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() accountKeeper.EXPECT().GetModuleAddress(types.StreamAccount).Return(streamAcc.GetAddress()) s.authKeeper = accountKeeper @@ -102,12 +104,14 @@ func (s *KeeperTestSuite) mockWithdrawContinuousFund() { s.stakingKeeper.EXPECT().BondDenom(gomock.Any()).Return("stake", nil).AnyTimes() } -func (s *KeeperTestSuite) mockStreamFunds() { +func (s *KeeperTestSuite) mockStreamFunds(distributed math.Int) { s.authKeeper.EXPECT().GetModuleAccount(s.ctx, types.ModuleName).Return(poolAcc).AnyTimes() + s.authKeeper.EXPECT().GetModuleAccount(s.ctx, types.ProtocolPoolDistrAccount).Return(poolDistrAcc).AnyTimes() s.authKeeper.EXPECT().GetModuleAddress(types.StreamAccount).Return(streamAcc.GetAddress()).AnyTimes() - distrBal := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - s.bankKeeper.EXPECT().GetAllBalances(s.ctx, poolAcc.GetAddress()).Return(distrBal).AnyTimes() - s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolAcc.GetName(), streamAcc.GetName(), gomock.Any()).AnyTimes() + distrBal := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, distributed)) + s.bankKeeper.EXPECT().GetAllBalances(s.ctx, poolDistrAcc.GetAddress()).Return(distrBal).AnyTimes() + s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolDistrAcc.GetName(), streamAcc.GetName(), gomock.Any()).AnyTimes() + s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolDistrAcc.GetName(), poolAcc.GetName(), gomock.Any()).AnyTimes() } func TestKeeperTestSuite(t *testing.T) { @@ -118,10 +122,11 @@ func (s *KeeperTestSuite) TestIterateAndUpdateFundsDistribution() { // We'll create 2 continuous funds of 30% each, and the total pool is 1000000, meaning each fund should get 300000 s.SetupTest() - s.authKeeper.EXPECT().GetModuleAccount(s.ctx, types.ModuleName).Return(poolAcc).AnyTimes() + s.authKeeper.EXPECT().GetModuleAccount(s.ctx, types.ProtocolPoolDistrAccount).Return(poolAcc).AnyTimes() distrBal := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1000000))) s.bankKeeper.EXPECT().GetAllBalances(s.ctx, poolAcc.GetAddress()).Return(distrBal).AnyTimes() - s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolAcc.GetName(), streamAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(600000)))).AnyTimes() + s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolDistrAcc.GetName(), streamAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(600000)))) + s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, poolDistrAcc.GetName(), poolAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(400000)))) _, err := s.msgServer.CreateContinuousFund(s.ctx, &types.MsgCreateContinuousFund{ Authority: s.poolKeeper.GetAuthority(), @@ -137,7 +142,7 @@ func (s *KeeperTestSuite) TestIterateAndUpdateFundsDistribution() { }) s.Require().NoError(err) - _ = s.poolKeeper.SetToDistribute(s.ctx, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000000))), s.poolKeeper.GetAuthority()) + _ = s.poolKeeper.SetToDistribute(s.ctx) err = s.poolKeeper.IterateAndUpdateFundsDistribution(s.ctx) s.Require().NoError(err) diff --git a/x/protocolpool/keeper/msg_server.go b/x/protocolpool/keeper/msg_server.go index 775826cda75..43caff3e42a 100644 --- a/x/protocolpool/keeper/msg_server.go +++ b/x/protocolpool/keeper/msg_server.go @@ -139,6 +139,11 @@ func (k MsgServer) CreateContinuousFund(ctx context.Context, msg *types.MsgCreat return nil, fmt.Errorf("cannot set continuous fund proposal\ntotal funds percentage exceeds 100\ncurrent total percentage: %s", totalStreamFundsPercentage.Sub(msg.Percentage).MulInt64(100).TruncateInt().String()) } + // Distribute funds to avoid giving this new fund more than it should get + if err := k.IterateAndUpdateFundsDistribution(ctx); err != nil { + return nil, err + } + // Create continuous fund proposal cf := types.ContinuousFund{ Recipient: msg.Recipient, @@ -161,12 +166,23 @@ func (k MsgServer) CreateContinuousFund(ctx context.Context, msg *types.MsgCreat } func (k MsgServer) WithdrawContinuousFund(ctx context.Context, msg *types.MsgWithdrawContinuousFund) (*types.MsgWithdrawContinuousFundResponse, error) { - amount, err := k.withdrawContinuousFund(ctx, msg.RecipientAddress) + recipient, err := k.authKeeper.AddressCodec().StringToBytes(msg.RecipientAddress) if err != nil { - return nil, err + return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid recipient address: %s", err) + } + + err = k.IterateAndUpdateFundsDistribution(ctx) + if err != nil { + return nil, fmt.Errorf("error while iterating all the continuous funds: %w", err) + } + + // withdraw continuous fund + withdrawnAmount, err := k.withdrawRecipientFunds(ctx, recipient) + if err != nil { + return nil, fmt.Errorf("error while withdrawing recipient funds for recipient: %w", err) } - return &types.MsgWithdrawContinuousFundResponse{Amount: amount}, nil + return &types.MsgWithdrawContinuousFundResponse{Amount: withdrawnAmount}, nil } func (k MsgServer) CancelContinuousFund(ctx context.Context, msg *types.MsgCancelContinuousFund) (*types.MsgCancelContinuousFundResponse, error) { @@ -182,17 +198,14 @@ func (k MsgServer) CancelContinuousFund(ctx context.Context, msg *types.MsgCance canceledHeight := k.HeaderService.HeaderInfo(ctx).Height canceledTime := k.HeaderService.HeaderInfo(ctx).Time - found, err := k.ContinuousFund.Has(ctx, recipient) - if !found { - return nil, fmt.Errorf("no recipient found to cancel continuous fund: %s", msg.RecipientAddress) - } - if err != nil { + // distribute funds before withdrawing + if err = k.IterateAndUpdateFundsDistribution(ctx); err != nil { return nil, err } // withdraw funds if any are allocated withdrawnFunds, err := k.withdrawRecipientFunds(ctx, recipient) - if err != nil && !errorspkg.Is(err, types.ErrNoRecipientFund) { + if err != nil && !errorspkg.Is(err, types.ErrNoRecipientFound) { return nil, fmt.Errorf("error while withdrawing already allocated funds for recipient %s: %w", msg.RecipientAddress, err) } diff --git a/x/protocolpool/keeper/msg_server_test.go b/x/protocolpool/keeper/msg_server_test.go index 37b122170d7..b053ef9ff68 100644 --- a/x/protocolpool/keeper/msg_server_test.go +++ b/x/protocolpool/keeper/msg_server_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "time" + "github.com/golang/mock/gomock" + "cosmossdk.io/collections" "cosmossdk.io/core/header" "cosmossdk.io/math" @@ -403,7 +405,7 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { "recipient with no continuous fund": { recipientAddress: []sdk.AccAddress{recipient}, expErr: true, - expErrMsg: "no continuous fund found for recipient", + expErrMsg: "error while withdrawing recipient funds for recipient: no recipient found", }, "funds percentage > 100": { preRun: func() { @@ -441,14 +443,14 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { suite.Require().NoError(err) // Set ToDistribute - err = suite.poolKeeper.ToDistribute.Set(suite.ctx, math.NewInt(100000)) + err = suite.poolKeeper.Distributions.Set(suite.ctx, suite.ctx.HeaderInfo().Time, math.NewInt(100000)) suite.Require().NoError(err) }, recipientAddress: []sdk.AccAddress{recipient}, expErr: true, expErrMsg: "error while iterating all the continuous funds: total funds percentage cannot exceed 100", }, - "expired case": { + "expired case with no funds left to withdraw": { preRun: func() { percentage, err := math.LegacyNewDecFromStr("0.2") suite.Require().NoError(err) @@ -464,7 +466,7 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { }, recipientAddress: []sdk.AccAddress{recipient}, expErr: true, - expErrMsg: "cannot withdraw continuous funds: continuous fund expired for recipient", + expErrMsg: "error while withdrawing recipient funds for recipient: no recipient found", }, "valid case with ToDistribute amount zero": { preRun: func() { @@ -483,8 +485,9 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { // Set recipient fund percentage and recipient fund distribution err = suite.poolKeeper.RecipientFundDistribution.Set(suite.ctx, recipient, math.ZeroInt()) suite.Require().NoError(err) - err = suite.poolKeeper.ToDistribute.Set(suite.ctx, math.ZeroInt()) + err = suite.poolKeeper.Distributions.Set(suite.ctx, suite.ctx.HeaderInfo().Time, math.ZeroInt()) suite.Require().NoError(err) + suite.mockStreamFunds(math.NewInt(0)) }, recipientAddress: []sdk.AccAddress{recipient}, expErr: false, @@ -504,9 +507,8 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { // Set recipient fund percentage and recipient fund distribution err = suite.poolKeeper.RecipientFundDistribution.Set(suite.ctx, recipient, math.ZeroInt()) suite.Require().NoError(err) - toDistribute := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) }, recipientAddress: []sdk.AccAddress{recipient}, @@ -530,9 +532,8 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { // Set recipient fund percentage and recipient fund distribution err = suite.poolKeeper.RecipientFundDistribution.Set(suite.ctx, recipient, math.ZeroInt()) suite.Require().NoError(err) - toDistribute := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) }, recipientAddress: []sdk.AccAddress{recipient}, @@ -588,9 +589,8 @@ func (suite *KeeperTestSuite) TestWithdrawContinuousFund() { err = suite.poolKeeper.RecipientFundDistribution.Set(suite.ctx, recipient3, math.ZeroInt()) suite.Require().NoError(err) - toDistribute := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) }, recipientAddress: []sdk.AccAddress{recipient, recipient2, recipient3}, @@ -813,11 +813,6 @@ func (suite *KeeperTestSuite) TestCancelContinuousFund() { expErr: true, expErrMsg: "empty address string is not allowed", }, - "no recipient found": { - recipientAddr: recipientAddr, - expErr: true, - expErrMsg: "no recipient found to cancel continuous fund", - }, "all good with unclaimed funds for recipient": { preRun: func() { // Set fund 1 @@ -853,9 +848,8 @@ func (suite *KeeperTestSuite) TestCancelContinuousFund() { suite.Require().NoError(err) // Set ToDistribute - toDistribute := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) // withdraw funds for fund request 2 @@ -960,9 +954,8 @@ func (suite *KeeperTestSuite) TestWithdrawExpiredFunds() { }) suite.Require().NoError(err) - toDistribute := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100000))) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) suite.mockWithdrawContinuousFund() @@ -973,11 +966,17 @@ func (suite *KeeperTestSuite) TestWithdrawExpiredFunds() { header.Time = expiration.Add(1 * time.Second) suite.ctx = suite.ctx.WithHeaderInfo(header) - _, err = suite.msgServer.WithdrawContinuousFund(suite.ctx, &types.MsgWithdrawContinuousFund{RecipientAddress: recipientStrAddr}) - suite.Require().ErrorContains(err, "continuous fund expired for recipient") + // If we keep calling WithdrawContinuousFund, it should not error and return always an amount of 0 + withdrawRes, err := suite.msgServer.WithdrawContinuousFund(suite.ctx, &types.MsgWithdrawContinuousFund{RecipientAddress: recipientStrAddr}) + suite.Require().True(withdrawRes.Amount.IsZero()) + suite.Require().NoError(err) + + withdrawRes, err = suite.msgServer.WithdrawContinuousFund(suite.ctx, &types.MsgWithdrawContinuousFund{RecipientAddress: recipientStrAddr}) + suite.Require().True(withdrawRes.Amount.IsZero()) + suite.Require().NoError(err) - suite.mockStreamFunds() - err = suite.poolKeeper.SetToDistribute(suite.ctx, toDistribute, suite.poolKeeper.GetAuthority()) + suite.mockStreamFunds(math.NewInt(100000)) + err = suite.poolKeeper.SetToDistribute(suite.ctx) suite.Require().NoError(err) suite.mockWithdrawContinuousFund() @@ -985,9 +984,58 @@ func (suite *KeeperTestSuite) TestWithdrawExpiredFunds() { suite.Require().NoError(err) res, err := suite.msgServer.CancelContinuousFund(suite.ctx, &types.MsgCancelContinuousFund{ + Authority: suite.poolKeeper.GetAuthority(), + RecipientAddress: recipient2StrAddr, + }) + suite.Require().NoError(err) + suite.Require().Equal(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(0)), res.WithdrawnAllocatedFund) + + // canceling an expired continuous fund, won't error + res, err = suite.msgServer.CancelContinuousFund(suite.ctx, &types.MsgCancelContinuousFund{ Authority: suite.poolKeeper.GetAuthority(), RecipientAddress: recipientStrAddr, }) suite.Require().NoError(err) suite.Require().Equal(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(0)), res.WithdrawnAllocatedFund) + + // if we try to cancel again the same continuout fund, it won't error, it will still distribute funds if needed. + res, err = suite.msgServer.CancelContinuousFund(suite.ctx, &types.MsgCancelContinuousFund{ + Authority: suite.poolKeeper.GetAuthority(), + RecipientAddress: recipientStrAddr, + }) + suite.Require().NoError(err) + suite.Require().True(res.WithdrawnAllocatedFund.IsNil()) +} + +func (suite *KeeperTestSuite) TestFundCommunityPool() { + sender := []byte("fundingAddr1____________________") + addrCodec := codectestutil.CodecOptions{}.GetAddressCodec() + senderAddr, err := addrCodec.BytesToString(sender) + suite.Require().NoError(err) + + amount := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000)) + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), sender, types.ModuleName, amount).Return(nil).Times(1) + + _, err = suite.msgServer.FundCommunityPool(suite.ctx, &types.MsgFundCommunityPool{ + Amount: amount, + Depositor: senderAddr, + }) + suite.Require().NoError(err) +} + +func (suite *KeeperTestSuite) TestCommunityPoolSpend() { + recipient := []byte("fundingAddr1____________________") + addrCodec := codectestutil.CodecOptions{}.GetAddressCodec() + recipientAddr, err := addrCodec.BytesToString(recipient) + suite.Require().NoError(err) + + amount := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000)) + suite.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), types.ModuleName, recipient, amount).Return(nil).Times(1) + + _, err = suite.msgServer.CommunityPoolSpend(suite.ctx, &types.MsgCommunityPoolSpend{ + Authority: suite.poolKeeper.GetAuthority(), + Recipient: recipientAddr, + Amount: amount, + }) + suite.Require().NoError(err) } diff --git a/x/protocolpool/module.go b/x/protocolpool/module.go index 882da6eb6fc..2e88385d54f 100644 --- a/x/protocolpool/module.go +++ b/x/protocolpool/module.go @@ -29,6 +29,7 @@ var ( _ appmodule.HasServices = AppModule{} _ appmodule.HasGenesis = AppModule{} _ appmodule.HasRegisterInterfaces = AppModule{} + _ appmodule.HasBeginBlocker = AppModule{} ) // AppModule implements an application module for the pool module @@ -112,5 +113,10 @@ func (am AppModule) ExportGenesis(ctx context.Context) (json.RawMessage, error) return am.cdc.MarshalJSON(gs) } +// BeginBlock implements appmodule.HasBeginBlocker. +func (am AppModule) BeginBlock(ctx context.Context) error { + return am.keeper.BeginBlocker(ctx) +} + // ConsensusVersion implements HasConsensusVersion func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion } diff --git a/x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto b/x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto index 5730f525780..d9df6870a7a 100644 --- a/x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto +++ b/x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto @@ -6,6 +6,7 @@ option go_package = "cosmossdk.io/x/protocolpool/types"; import "cosmos/protocolpool/v1/types.proto"; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; // GenesisState defines the protocolpool module's genesis state. message GenesisState { @@ -14,9 +15,26 @@ message GenesisState { // Budget defines the budget proposals at genesis. repeated Budget budget = 2; - string to_distribute = 3 [ + // last_balance contains the amount of tokens yet to be distributed, will be zero if + // there are no funds to distribute. + string last_balance = 3 [ (cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "cosmossdk.io/math.Int", (gogoproto.nullable) = false ]; + + // distributions contains the list of distributions to be made to continuous + // funds and budgets. It contains time in order to distribute to non-expired + // funds only. + repeated Distribution distributions = 4; } + +message Distribution { + string amount = 3 [ + (cosmos_proto.scalar) = "cosmos.Int", + (gogoproto.customtype) = "cosmossdk.io/math.Int", + (gogoproto.nullable) = false + ]; + + google.protobuf.Timestamp time = 6 [(gogoproto.stdtime) = true]; +} \ No newline at end of file diff --git a/x/protocolpool/types/errors.go b/x/protocolpool/types/errors.go index a3790136b97..160e30dc8a2 100644 --- a/x/protocolpool/types/errors.go +++ b/x/protocolpool/types/errors.go @@ -3,6 +3,6 @@ package types import "cosmossdk.io/errors" var ( - ErrInvalidSigner = errors.Register(ModuleName, 2, "expected authority account as only signer for community pool spend message") - ErrNoRecipientFund = errors.Register(ModuleName, 3, "no recipient found") + ErrInvalidSigner = errors.Register(ModuleName, 2, "expected authority account as only signer for community pool spend message") + ErrNoRecipientFound = errors.Register(ModuleName, 3, "no recipient found") ) diff --git a/x/protocolpool/types/genesis.go b/x/protocolpool/types/genesis.go index 632a3657346..08ad95eaf4b 100644 --- a/x/protocolpool/types/genesis.go +++ b/x/protocolpool/types/genesis.go @@ -13,6 +13,8 @@ func NewGenesisState(cf []*ContinuousFund, budget []*Budget) *GenesisState { return &GenesisState{ ContinuousFund: cf, Budget: budget, + LastBalance: math.ZeroInt(), + Distributions: []*Distribution{}, } } diff --git a/x/protocolpool/types/genesis.pb.go b/x/protocolpool/types/genesis.pb.go index ee3d8393808..8118de396b5 100644 --- a/x/protocolpool/types/genesis.pb.go +++ b/x/protocolpool/types/genesis.pb.go @@ -9,15 +9,19 @@ import ( _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -30,8 +34,14 @@ type GenesisState struct { // ContinuousFund defines the continuous funds at genesis. ContinuousFund []*ContinuousFund `protobuf:"bytes,1,rep,name=continuous_fund,json=continuousFund,proto3" json:"continuous_fund,omitempty"` // Budget defines the budget proposals at genesis. - Budget []*Budget `protobuf:"bytes,2,rep,name=budget,proto3" json:"budget,omitempty"` - ToDistribute cosmossdk_io_math.Int `protobuf:"bytes,3,opt,name=to_distribute,json=toDistribute,proto3,customtype=cosmossdk.io/math.Int" json:"to_distribute"` + Budget []*Budget `protobuf:"bytes,2,rep,name=budget,proto3" json:"budget,omitempty"` + // last_balance contains the amount of tokens yet to be distributed, will be zero if + // there are no funds to distribute. + LastBalance cosmossdk_io_math.Int `protobuf:"bytes,3,opt,name=last_balance,json=lastBalance,proto3,customtype=cosmossdk.io/math.Int" json:"last_balance"` + // distributions contains the list of distributions to be made to continuous + // funds and budgets. It contains time in order to distribute to non-expired + // funds only. + Distributions []*Distribution `protobuf:"bytes,4,rep,name=distributions,proto3" json:"distributions,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -81,8 +91,61 @@ func (m *GenesisState) GetBudget() []*Budget { return nil } +func (m *GenesisState) GetDistributions() []*Distribution { + if m != nil { + return m.Distributions + } + return nil +} + +type Distribution struct { + Amount cosmossdk_io_math.Int `protobuf:"bytes,3,opt,name=amount,proto3,customtype=cosmossdk.io/math.Int" json:"amount"` + Time *time.Time `protobuf:"bytes,6,opt,name=time,proto3,stdtime" json:"time,omitempty"` +} + +func (m *Distribution) Reset() { *m = Distribution{} } +func (m *Distribution) String() string { return proto.CompactTextString(m) } +func (*Distribution) ProtoMessage() {} +func (*Distribution) Descriptor() ([]byte, []int) { + return fileDescriptor_72560a99455b4146, []int{1} +} +func (m *Distribution) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Distribution) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Distribution.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 *Distribution) XXX_Merge(src proto.Message) { + xxx_messageInfo_Distribution.Merge(m, src) +} +func (m *Distribution) XXX_Size() int { + return m.Size() +} +func (m *Distribution) XXX_DiscardUnknown() { + xxx_messageInfo_Distribution.DiscardUnknown(m) +} + +var xxx_messageInfo_Distribution proto.InternalMessageInfo + +func (m *Distribution) GetTime() *time.Time { + if m != nil { + return m.Time + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "cosmos.protocolpool.v1.GenesisState") + proto.RegisterType((*Distribution)(nil), "cosmos.protocolpool.v1.Distribution") } func init() { @@ -90,26 +153,32 @@ func init() { } var fileDescriptor_72560a99455b4146 = []byte{ - // 290 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x49, 0xce, 0x2f, 0xce, - 0xcd, 0x2f, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0x29, 0xc8, 0xcf, 0xcf, 0xd1, - 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x03, 0x8b, 0x0b, 0x89, 0x41, - 0x54, 0xe9, 0x21, 0xab, 0xd2, 0x2b, 0x33, 0x94, 0x52, 0xc2, 0xa1, 0xbb, 0xa4, 0xb2, 0x20, 0x15, - 0xaa, 0x5a, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xcc, 0xd4, 0x07, 0xb1, 0xa0, 0xa2, 0x92, 0x10, - 0x9d, 0xf1, 0x10, 0x09, 0x64, 0xe3, 0x95, 0x5e, 0x32, 0x72, 0xf1, 0xb8, 0x43, 0xac, 0x0f, 0x2e, - 0x49, 0x2c, 0x49, 0x15, 0xf2, 0xe7, 0xe2, 0x4f, 0xce, 0xcf, 0x2b, 0xc9, 0xcc, 0x2b, 0xcd, 0x2f, - 0x2d, 0x8e, 0x4f, 0x2b, 0xcd, 0x4b, 0x91, 0x60, 0x54, 0x60, 0xd6, 0xe0, 0x36, 0x52, 0xd3, 0xc3, - 0xee, 0x2e, 0x3d, 0x67, 0xb8, 0x72, 0xb7, 0xd2, 0xbc, 0x94, 0x20, 0xbe, 0x64, 0x14, 0xbe, 0x90, - 0x19, 0x17, 0x5b, 0x52, 0x69, 0x4a, 0x7a, 0x6a, 0x89, 0x04, 0x13, 0xd8, 0x1c, 0x39, 0x5c, 0xe6, - 0x38, 0x81, 0x55, 0x05, 0x41, 0x55, 0x0b, 0x05, 0x70, 0xf1, 0x96, 0xe4, 0xc7, 0xa7, 0x64, 0x16, - 0x97, 0x14, 0x65, 0x26, 0x95, 0x96, 0xa4, 0x4a, 0x30, 0x2b, 0x30, 0x6a, 0x70, 0x3a, 0x69, 0x9f, - 0xb8, 0x27, 0xcf, 0x70, 0xeb, 0x9e, 0xbc, 0x28, 0xc4, 0x94, 0xe2, 0x94, 0x6c, 0xbd, 0xcc, 0x7c, - 0xfd, 0xdc, 0xc4, 0x92, 0x0c, 0x3d, 0xcf, 0xbc, 0x92, 0x4b, 0x5b, 0x74, 0xb9, 0xa0, 0xc6, 0x7b, - 0xe6, 0x95, 0x04, 0xf1, 0x94, 0xe4, 0xbb, 0xc0, 0x0d, 0x70, 0xb2, 0x3e, 0xf1, 0x48, 0x8e, 0xf1, - 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, - 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x45, 0x14, 0xc3, 0x2a, 0x50, 0x83, 0x18, 0x1c, 0xbe, 0x49, - 0x6c, 0x60, 0x31, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1e, 0x8d, 0xab, 0x75, 0xc4, 0x01, - 0x00, 0x00, + // 393 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xcf, 0xca, 0xd3, 0x40, + 0x14, 0xc5, 0x33, 0x5f, 0x4b, 0xc0, 0x69, 0x55, 0x08, 0x2a, 0x31, 0x8b, 0xa4, 0x96, 0x22, 0x05, + 0x71, 0x42, 0xab, 0xb8, 0x71, 0x97, 0x8a, 0x52, 0x17, 0x0a, 0xd1, 0x95, 0x9b, 0x92, 0x3f, 0xd3, + 0x18, 0x4c, 0xe6, 0x86, 0xce, 0x4c, 0xd1, 0x47, 0x70, 0xd7, 0x77, 0xd1, 0x87, 0xe8, 0xb2, 0xb8, + 0x12, 0x17, 0x55, 0xda, 0x17, 0x91, 0xce, 0xa4, 0x92, 0x80, 0xdd, 0x7c, 0xbb, 0xc9, 0xbd, 0xbf, + 0x73, 0x72, 0xe0, 0x5c, 0x3c, 0x4a, 0x80, 0x97, 0xc0, 0xfd, 0x6a, 0x05, 0x02, 0x12, 0x28, 0x2a, + 0x80, 0xc2, 0x5f, 0x4f, 0xfc, 0x8c, 0x32, 0xca, 0x73, 0x4e, 0xd4, 0xdc, 0xba, 0xa7, 0x29, 0xd2, + 0xa4, 0xc8, 0x7a, 0xe2, 0x0c, 0x2f, 0xa8, 0xc5, 0x97, 0x8a, 0xd6, 0xb4, 0x73, 0x27, 0x83, 0x0c, + 0xd4, 0xd3, 0x3f, 0xbd, 0xea, 0xe9, 0x7d, 0xad, 0x5c, 0xe8, 0x45, 0xd3, 0xde, 0xf1, 0x32, 0x80, + 0xac, 0xa0, 0xda, 0x34, 0x96, 0x4b, 0x5f, 0xe4, 0x25, 0xe5, 0x22, 0x2a, 0x2b, 0x0d, 0x0c, 0xbf, + 0x5d, 0xe1, 0xfe, 0x2b, 0x9d, 0xef, 0x9d, 0x88, 0x04, 0xb5, 0xde, 0xe2, 0xdb, 0x09, 0x30, 0x91, + 0x33, 0x09, 0x92, 0x2f, 0x96, 0x92, 0xa5, 0x36, 0x1a, 0x74, 0xc6, 0xbd, 0xe9, 0x43, 0xf2, 0xff, + 0xe0, 0x64, 0xf6, 0x0f, 0x7f, 0x29, 0x59, 0x1a, 0xde, 0x4a, 0x5a, 0xdf, 0xd6, 0x33, 0x6c, 0xc6, + 0x32, 0xcd, 0xa8, 0xb0, 0xaf, 0x94, 0x8f, 0x7b, 0xc9, 0x27, 0x50, 0x54, 0x58, 0xd3, 0xd6, 0x1b, + 0xdc, 0x2f, 0x22, 0x2e, 0x16, 0x71, 0x54, 0x44, 0x2c, 0xa1, 0x76, 0x67, 0x80, 0xc6, 0x37, 0x82, + 0x47, 0xdb, 0xbd, 0x67, 0xfc, 0xda, 0x7b, 0x77, 0xb5, 0x09, 0x4f, 0x3f, 0x91, 0x1c, 0xfc, 0x32, + 0x12, 0x1f, 0xc9, 0x9c, 0x89, 0x1f, 0xdf, 0x1f, 0xe3, 0xda, 0x7d, 0xce, 0x44, 0xd8, 0x3b, 0x19, + 0x04, 0x5a, 0x6f, 0xbd, 0xc6, 0x37, 0xd3, 0x9c, 0x8b, 0x55, 0x1e, 0x4b, 0x91, 0x03, 0xe3, 0x76, + 0x57, 0xc5, 0x19, 0x5d, 0x8a, 0xf3, 0xa2, 0x01, 0x87, 0x6d, 0xe9, 0xf0, 0x2b, 0xc2, 0xfd, 0xe6, + 0xde, 0x9a, 0x61, 0x33, 0x2a, 0x41, 0x32, 0x71, 0x9d, 0x98, 0xb5, 0xd4, 0x7a, 0x8a, 0xbb, 0xa7, + 0x7a, 0x6c, 0x73, 0x80, 0xc6, 0xbd, 0xa9, 0x43, 0x74, 0x77, 0xe4, 0xdc, 0x1d, 0x79, 0x7f, 0xee, + 0x2e, 0xe8, 0x6e, 0x7e, 0x7b, 0x28, 0x54, 0x74, 0xf0, 0x7c, 0x7b, 0x70, 0xd1, 0xee, 0xe0, 0xa2, + 0x3f, 0x07, 0x17, 0x6d, 0x8e, 0xae, 0xb1, 0x3b, 0xba, 0xc6, 0xcf, 0xa3, 0x6b, 0x7c, 0x78, 0xd0, + 0xfa, 0xf9, 0xe7, 0xf6, 0x65, 0xa9, 0xb3, 0x8a, 0x4d, 0x35, 0x7b, 0xf2, 0x37, 0x00, 0x00, 0xff, + 0xff, 0x0c, 0x77, 0xdd, 0xf7, 0xbb, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -132,10 +201,24 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Distributions) > 0 { + for iNdEx := len(m.Distributions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Distributions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } { - size := m.ToDistribute.Size() + size := m.LastBalance.Size() i -= size - if _, err := m.ToDistribute.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.LastBalance.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintGenesis(dAtA, i, uint64(size)) @@ -173,6 +256,49 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Distribution) 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 *Distribution) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Distribution) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Time != nil { + n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.Time):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintGenesis(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x32 + } + { + size := m.Amount.Size() + i -= size + if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -202,8 +328,29 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - l = m.ToDistribute.Size() + l = m.LastBalance.Size() n += 1 + l + sovGenesis(uint64(l)) + if len(m.Distributions) > 0 { + for _, e := range m.Distributions { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *Distribution) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Amount.Size() + n += 1 + l + sovGenesis(uint64(l)) + if m.Time != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.Time) + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -312,7 +459,125 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ToDistribute", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastBalance", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastBalance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Distributions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Distributions = append(m.Distributions, &Distribution{}) + if err := m.Distributions[len(m.Distributions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Distribution) 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 ErrIntOverflowGenesis + } + 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: Distribution: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Distribution: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -340,7 +605,43 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ToDistribute.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Time == nil { + m.Time = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/protocolpool/types/keys.go b/x/protocolpool/types/keys.go index acb721c5edd..072052937b5 100644 --- a/x/protocolpool/types/keys.go +++ b/x/protocolpool/types/keys.go @@ -9,6 +9,9 @@ const ( // StreamAccount is the name constant used for stream account StreamAccount = "stream_acc" + // ProtocolPoolDistrAccount is an intermediary account that holds the funds to be distributed to the protocolpool accounts. + ProtocolPoolDistrAccount = "protocolpool_distr" + // StoreKey is the store key string for protocolpool StoreKey = ModuleName @@ -26,5 +29,6 @@ var ( ContinuousFundKey = collections.NewPrefix(3) RecipientFundPercentageKey = collections.NewPrefix(4) RecipientFundDistributionKey = collections.NewPrefix(5) - ToDistributeKey = collections.NewPrefix(6) + DistributionsKey = collections.NewPrefix(6) + LastBalanceKey = collections.NewPrefix(7) )