diff --git a/api/cosmos/group/v1beta1/genesis.pulsar.go b/api/cosmos/group/v1beta1/genesis.pulsar.go index 1179d09b7c..c59e4053c8 100644 --- a/api/cosmos/group/v1beta1/genesis.pulsar.go +++ b/api/cosmos/group/v1beta1/genesis.pulsar.go @@ -2,14 +2,13 @@ package groupv1beta1 import ( fmt "fmt" - io "io" - reflect "reflect" - sync "sync" - runtime "github.com/cosmos/cosmos-proto/runtime" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" ) var _ protoreflect.List = (*_GenesisState_2_list)(nil) @@ -268,15 +267,15 @@ func (x *_GenesisState_8_list) IsValid() bool { } var ( - md_GenesisState protoreflect.MessageDescriptor - fd_GenesisState_group_seq protoreflect.FieldDescriptor - fd_GenesisState_groups protoreflect.FieldDescriptor - fd_GenesisState_group_members protoreflect.FieldDescriptor - fd_GenesisState_group_policy_account_seq protoreflect.FieldDescriptor - fd_GenesisState_group_policies protoreflect.FieldDescriptor - fd_GenesisState_proposal_seq protoreflect.FieldDescriptor - fd_GenesisState_proposals protoreflect.FieldDescriptor - fd_GenesisState_votes protoreflect.FieldDescriptor + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_group_seq protoreflect.FieldDescriptor + fd_GenesisState_groups protoreflect.FieldDescriptor + fd_GenesisState_group_members protoreflect.FieldDescriptor + fd_GenesisState_group_policy_seq protoreflect.FieldDescriptor + fd_GenesisState_group_policies protoreflect.FieldDescriptor + fd_GenesisState_proposal_seq protoreflect.FieldDescriptor + fd_GenesisState_proposals protoreflect.FieldDescriptor + fd_GenesisState_votes protoreflect.FieldDescriptor ) func init() { @@ -285,7 +284,7 @@ func init() { fd_GenesisState_group_seq = md_GenesisState.Fields().ByName("group_seq") fd_GenesisState_groups = md_GenesisState.Fields().ByName("groups") fd_GenesisState_group_members = md_GenesisState.Fields().ByName("group_members") - fd_GenesisState_group_policy_account_seq = md_GenesisState.Fields().ByName("group_policy_account_seq") + fd_GenesisState_group_policy_seq = md_GenesisState.Fields().ByName("group_policy_seq") fd_GenesisState_group_policies = md_GenesisState.Fields().ByName("group_policies") fd_GenesisState_proposal_seq = md_GenesisState.Fields().ByName("proposal_seq") fd_GenesisState_proposals = md_GenesisState.Fields().ByName("proposals") @@ -375,9 +374,9 @@ func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, return } } - if x.GroupPolicyAccountSeq != uint64(0) { - value := protoreflect.ValueOfUint64(x.GroupPolicyAccountSeq) - if !f(fd_GenesisState_group_policy_account_seq, value) { + if x.GroupPolicySeq != uint64(0) { + value := protoreflect.ValueOfUint64(x.GroupPolicySeq) + if !f(fd_GenesisState_group_policy_seq, value) { return } } @@ -426,8 +425,8 @@ func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool return len(x.Groups) != 0 case "cosmos.group.v1beta1.GenesisState.group_members": return len(x.GroupMembers) != 0 - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": - return x.GroupPolicyAccountSeq != uint64(0) + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": + return x.GroupPolicySeq != uint64(0) case "cosmos.group.v1beta1.GenesisState.group_policies": return len(x.GroupPolicies) != 0 case "cosmos.group.v1beta1.GenesisState.proposal_seq": @@ -458,8 +457,8 @@ func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { x.Groups = nil case "cosmos.group.v1beta1.GenesisState.group_members": x.GroupMembers = nil - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": - x.GroupPolicyAccountSeq = uint64(0) + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": + x.GroupPolicySeq = uint64(0) case "cosmos.group.v1beta1.GenesisState.group_policies": x.GroupPolicies = nil case "cosmos.group.v1beta1.GenesisState.proposal_seq": @@ -499,8 +498,8 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto } listValue := &_GenesisState_3_list{list: &x.GroupMembers} return protoreflect.ValueOfList(listValue) - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": - value := x.GroupPolicyAccountSeq + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": + value := x.GroupPolicySeq return protoreflect.ValueOfUint64(value) case "cosmos.group.v1beta1.GenesisState.group_policies": if len(x.GroupPolicies) == 0 { @@ -553,8 +552,8 @@ func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value lv := value.List() clv := lv.(*_GenesisState_3_list) x.GroupMembers = *clv.list - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": - x.GroupPolicyAccountSeq = value.Uint() + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": + x.GroupPolicySeq = value.Uint() case "cosmos.group.v1beta1.GenesisState.group_policies": lv := value.List() clv := lv.(*_GenesisState_5_list) @@ -621,8 +620,8 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p return protoreflect.ValueOfList(value) case "cosmos.group.v1beta1.GenesisState.group_seq": panic(fmt.Errorf("field group_seq of message cosmos.group.v1beta1.GenesisState is not mutable")) - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": - panic(fmt.Errorf("field group_policy_account_seq of message cosmos.group.v1beta1.GenesisState is not mutable")) + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": + panic(fmt.Errorf("field group_policy_seq of message cosmos.group.v1beta1.GenesisState is not mutable")) case "cosmos.group.v1beta1.GenesisState.proposal_seq": panic(fmt.Errorf("field proposal_seq of message cosmos.group.v1beta1.GenesisState is not mutable")) default: @@ -646,7 +645,7 @@ func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) case "cosmos.group.v1beta1.GenesisState.group_members": list := []*GroupMember{} return protoreflect.ValueOfList(&_GenesisState_3_list{list: &list}) - case "cosmos.group.v1beta1.GenesisState.group_policy_account_seq": + case "cosmos.group.v1beta1.GenesisState.group_policy_seq": return protoreflect.ValueOfUint64(uint64(0)) case "cosmos.group.v1beta1.GenesisState.group_policies": list := []*GroupPolicyInfo{} @@ -743,8 +742,8 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { n += 1 + l + runtime.Sov(uint64(l)) } } - if x.GroupPolicyAccountSeq != 0 { - n += 1 + runtime.Sov(uint64(x.GroupPolicyAccountSeq)) + if x.GroupPolicySeq != 0 { + n += 1 + runtime.Sov(uint64(x.GroupPolicySeq)) } if len(x.GroupPolicies) > 0 { for _, e := range x.GroupPolicies { @@ -849,8 +848,8 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { dAtA[i] = 0x2a } } - if x.GroupPolicyAccountSeq != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.GroupPolicyAccountSeq)) + if x.GroupPolicySeq != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.GroupPolicySeq)) i-- dAtA[i] = 0x20 } @@ -1029,9 +1028,9 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 4: if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field GroupPolicyAccountSeq", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field GroupPolicySeq", wireType) } - x.GroupPolicyAccountSeq = 0 + x.GroupPolicySeq = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -1041,7 +1040,7 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - x.GroupPolicyAccountSeq |= uint64(b&0x7F) << shift + x.GroupPolicySeq |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -1228,9 +1227,9 @@ type GenesisState struct { Groups []*GroupInfo `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty"` // group_members is the list of groups members. GroupMembers []*GroupMember `protobuf:"bytes,3,rep,name=group_members,json=groupMembers,proto3" json:"group_members,omitempty"` - // group_policy_account_seq is the group policy table orm.Sequence, + // group_policy_seq is the group policy table orm.Sequence, // it is used to generate the next group policy account address. - GroupPolicyAccountSeq uint64 `protobuf:"varint,4,opt,name=group_policy_account_seq,json=groupPolicyAccountSeq,proto3" json:"group_policy_account_seq,omitempty"` + GroupPolicySeq uint64 `protobuf:"varint,4,opt,name=group_policy_seq,json=groupPolicySeq,proto3" json:"group_policy_seq,omitempty"` // group_policies is the list of group policies info. GroupPolicies []*GroupPolicyInfo `protobuf:"bytes,5,rep,name=group_policies,json=groupPolicies,proto3" json:"group_policies,omitempty"` // proposal_seq is the proposal table orm.Sequence, @@ -1283,9 +1282,9 @@ func (x *GenesisState) GetGroupMembers() []*GroupMember { return nil } -func (x *GenesisState) GetGroupPolicyAccountSeq() uint64 { +func (x *GenesisState) GetGroupPolicySeq() uint64 { if x != nil { - return x.GroupPolicyAccountSeq + return x.GroupPolicySeq } return 0 } @@ -1326,7 +1325,7 @@ var file_cosmos_group_v1beta1_genesis_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, 0x03, 0x0a, + 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x03, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x06, 0x67, 0x72, @@ -1337,39 +1336,38 @@ var file_cosmos_group_v1beta1_genesis_proto_rawDesc = []byte{ 0x62, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0c, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x65, 0x71, 0x12, 0x4c, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, + 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x73, 0x65, 0x71, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x53, 0x65, 0x71, 0x12, 0x4c, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, + 0x73, 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x12, 0x3c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, + 0x61, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x52, + 0x05, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x42, 0xde, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x5f, 0x73, - 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x53, 0x65, 0x71, 0x12, 0x3c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, - 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, - 0x61, 0x6c, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x05, - 0x76, 0x6f, 0x74, 0x65, 0x73, 0x42, 0xde, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x47, 0x58, 0xaa, 0x02, 0x14, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xca, 0x02, 0x14, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x20, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, + 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x47, 0x58, 0xaa, 0x02, 0x14, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x56, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x14, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x20, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/cosmos/orm/v1alpha1/orm.pulsar.go b/api/cosmos/orm/v1alpha1/orm.pulsar.go index 203a359f11..11ff843144 100644 --- a/api/cosmos/orm/v1alpha1/orm.pulsar.go +++ b/api/cosmos/orm/v1alpha1/orm.pulsar.go @@ -2333,7 +2333,8 @@ type SecondaryIndexDescriptor struct { // store the remaining primary key fields in the value.. Fields string `protobuf:"bytes,1,opt,name=fields,proto3" json:"fields,omitempty"` // id is a non-zero integer ID that must be unique within the indexes for this - // table. It may be deprecated in the future when this can be auto-generated. + // table and less than 32768. It may be deprecated in the future when this can + // be auto-generated. Id uint32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` // unique specifies that this an unique index. Unique bool `protobuf:"varint,3,opt,name=unique,proto3" json:"unique,omitempty"` diff --git a/go.sum b/go.sum index d65a75fbaa..26d5fe9142 100644 --- a/go.sum +++ b/go.sum @@ -134,7 +134,6 @@ github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= diff --git a/proto/cosmos/group/v1beta1/genesis.proto b/proto/cosmos/group/v1beta1/genesis.proto index 0ad91e5279..33ebe20f86 100644 --- a/proto/cosmos/group/v1beta1/genesis.proto +++ b/proto/cosmos/group/v1beta1/genesis.proto @@ -19,9 +19,9 @@ message GenesisState { // group_members is the list of groups members. repeated GroupMember group_members = 3; - // group_policy_account_seq is the group policy table orm.Sequence, + // group_policy_seq is the group policy table orm.Sequence, // it is used to generate the next group policy account address. - uint64 group_policy_account_seq = 4; + uint64 group_policy_seq = 4; // group_policies is the list of group policies info. repeated GroupPolicyInfo group_policies = 5; diff --git a/x/group/genesis.pb.go b/x/group/genesis.pb.go index 81c290b897..786a6ad04b 100644 --- a/x/group/genesis.pb.go +++ b/x/group/genesis.pb.go @@ -31,9 +31,9 @@ type GenesisState struct { Groups []*GroupInfo `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty"` // group_members is the list of groups members. GroupMembers []*GroupMember `protobuf:"bytes,3,rep,name=group_members,json=groupMembers,proto3" json:"group_members,omitempty"` - // group_policy_account_seq is the group policy table orm.Sequence, + // group_policy_seq is the group policy table orm.Sequence, // it is used to generate the next group policy account address. - GroupPolicyAccountSeq uint64 `protobuf:"varint,4,opt,name=group_policy_account_seq,json=groupPolicyAccountSeq,proto3" json:"group_policy_account_seq,omitempty"` + GroupPolicySeq uint64 `protobuf:"varint,4,opt,name=group_policy_seq,json=groupPolicySeq,proto3" json:"group_policy_seq,omitempty"` // group_policies is the list of group policies info. GroupPolicies []*GroupPolicyInfo `protobuf:"bytes,5,rep,name=group_policies,json=groupPolicies,proto3" json:"group_policies,omitempty"` // proposal_seq is the proposal table orm.Sequence, @@ -99,9 +99,9 @@ func (m *GenesisState) GetGroupMembers() []*GroupMember { return nil } -func (m *GenesisState) GetGroupPolicyAccountSeq() uint64 { +func (m *GenesisState) GetGroupPolicySeq() uint64 { if m != nil { - return m.GroupPolicyAccountSeq + return m.GroupPolicySeq } return 0 } @@ -143,30 +143,29 @@ func init() { } var fileDescriptor_7eedba45e0e08e2c = []byte{ - // 355 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xcf, 0x4e, 0xf2, 0x40, - 0x14, 0xc5, 0xe9, 0xc7, 0x9f, 0x0f, 0x06, 0x70, 0x31, 0xd1, 0x64, 0x82, 0xc9, 0x08, 0x44, 0x13, - 0x36, 0xb6, 0xa2, 0x0b, 0x36, 0xc6, 0x44, 0x17, 0x12, 0x13, 0x4d, 0x48, 0x49, 0x5c, 0xb8, 0x21, - 0x6d, 0x1d, 0x6b, 0x23, 0x65, 0x4a, 0xef, 0x40, 0xe4, 0x2d, 0x7c, 0x2a, 0xe3, 0x92, 0xa5, 0x4b, - 0x03, 0x2f, 0x62, 0xb8, 0x53, 0x52, 0x17, 0x0d, 0x2b, 0xb8, 0x73, 0xcf, 0xef, 0x9c, 0xd3, 0xe4, - 0x92, 0xb6, 0x27, 0x21, 0x94, 0x60, 0xf9, 0xb1, 0x9c, 0x45, 0xd6, 0xbc, 0xeb, 0x0a, 0xe5, 0x74, - 0x2d, 0x5f, 0x4c, 0x04, 0x04, 0x60, 0x46, 0xb1, 0x54, 0x92, 0xee, 0x6b, 0x8d, 0x89, 0x1a, 0x33, - 0xd1, 0x34, 0x9a, 0x99, 0xa4, 0x5a, 0x44, 0x22, 0xe1, 0xda, 0x9f, 0x79, 0x52, 0xeb, 0x6b, 0xa7, - 0xa1, 0x72, 0x94, 0xa0, 0x87, 0xa4, 0x82, 0xea, 0x11, 0x88, 0x29, 0x33, 0x9a, 0x46, 0xa7, 0x60, - 0x97, 0xf1, 0x61, 0x28, 0xa6, 0xb4, 0x47, 0x4a, 0xf8, 0x1f, 0xd8, 0xbf, 0x66, 0xbe, 0x53, 0x3d, - 0x3f, 0x32, 0xb3, 0x62, 0xcd, 0xfe, 0x66, 0xba, 0x9b, 0xbc, 0x48, 0x3b, 0x91, 0xd3, 0x5b, 0x52, - 0xd7, 0xae, 0xa1, 0x08, 0x5d, 0x11, 0x03, 0xcb, 0x23, 0xdf, 0xda, 0xc1, 0x3f, 0xa0, 0xd2, 0xae, - 0xf9, 0xe9, 0x00, 0xb4, 0x47, 0x98, 0xf6, 0x89, 0xe4, 0x38, 0xf0, 0x16, 0x23, 0xc7, 0xf3, 0xe4, - 0x6c, 0xa2, 0xb0, 0x6c, 0x01, 0xcb, 0x1e, 0xe0, 0x7e, 0x80, 0xeb, 0x6b, 0xbd, 0xdd, 0x34, 0xbf, - 0x27, 0x7b, 0x7f, 0xc0, 0x40, 0x00, 0x2b, 0x62, 0x83, 0x93, 0x1d, 0x0d, 0xb4, 0x09, 0x7e, 0x47, - 0x3d, 0x75, 0x0d, 0x04, 0xd0, 0x16, 0xa9, 0x45, 0xb1, 0x8c, 0x24, 0x38, 0x63, 0x8c, 0x2e, 0x61, - 0x74, 0x75, 0xfb, 0xb6, 0x09, 0xbc, 0x24, 0x95, 0xed, 0x08, 0xec, 0x3f, 0x66, 0xf1, 0xec, 0xac, - 0x41, 0x22, 0xb3, 0x53, 0x80, 0x9e, 0x91, 0xe2, 0x5c, 0x2a, 0x01, 0xac, 0x8c, 0x64, 0x23, 0x9b, - 0x7c, 0x94, 0x4a, 0xd8, 0x5a, 0x78, 0x73, 0xf5, 0xb5, 0xe2, 0xc6, 0x72, 0xc5, 0x8d, 0x9f, 0x15, - 0x37, 0x3e, 0xd6, 0x3c, 0xb7, 0x5c, 0xf3, 0xdc, 0xf7, 0x9a, 0xe7, 0x9e, 0x8e, 0xfd, 0x40, 0xbd, - 0xce, 0x5c, 0xd3, 0x93, 0xa1, 0x95, 0xdc, 0x83, 0xfe, 0x39, 0x85, 0xe7, 0x37, 0xeb, 0x5d, 0x1f, - 0x87, 0x5b, 0xc2, 0x7b, 0xb8, 0xf8, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x7b, 0xee, 0x41, 0x6d, - 0x02, 0x00, 0x00, + // 346 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xbf, 0x4e, 0x3a, 0x41, + 0x10, 0xc7, 0xb9, 0x1f, 0x7f, 0x7e, 0xb0, 0xfc, 0x89, 0xd9, 0x58, 0x5c, 0x30, 0x59, 0x81, 0x68, + 0x42, 0xe3, 0x9d, 0x68, 0x61, 0x63, 0x2c, 0x2c, 0x24, 0x26, 0x9a, 0x90, 0x23, 0xb1, 0xb0, 0x31, + 0x1c, 0x8e, 0xe7, 0x45, 0x8e, 0x5d, 0x6e, 0x16, 0x22, 0x6f, 0xe1, 0xdb, 0xf8, 0x0a, 0x96, 0x94, + 0x96, 0x06, 0x5e, 0xc4, 0x30, 0x7b, 0x04, 0x8b, 0x0b, 0xd5, 0xee, 0x4c, 0x3e, 0xdf, 0xf9, 0x4c, + 0x31, 0xac, 0x35, 0x94, 0x18, 0x49, 0x74, 0x83, 0x58, 0x4e, 0x95, 0x3b, 0xeb, 0xf8, 0xa0, 0x07, + 0x1d, 0x37, 0x80, 0x31, 0x60, 0x88, 0x8e, 0x8a, 0xa5, 0x96, 0x7c, 0xdf, 0x30, 0x0e, 0x31, 0x4e, + 0xc2, 0xd4, 0x1b, 0xa9, 0x49, 0x3d, 0x57, 0x90, 0xe4, 0x5a, 0x9f, 0x59, 0x56, 0xe9, 0x9a, 0x49, + 0x7d, 0x3d, 0xd0, 0xc0, 0x0f, 0x58, 0x89, 0xe8, 0x27, 0x84, 0x89, 0x6d, 0x35, 0xac, 0x76, 0xce, + 0x2b, 0x52, 0xa3, 0x0f, 0x13, 0x7e, 0xc1, 0x0a, 0xf4, 0x47, 0xfb, 0x5f, 0x23, 0xdb, 0x2e, 0x9f, + 0x1d, 0x3a, 0x69, 0x5a, 0xa7, 0xbb, 0xae, 0x6e, 0xc7, 0x2f, 0xd2, 0x4b, 0x70, 0x7e, 0xc3, 0xaa, + 0x66, 0x6a, 0x04, 0x91, 0x0f, 0x31, 0xda, 0x59, 0xca, 0x37, 0x77, 0xe4, 0xef, 0x89, 0xf4, 0x2a, + 0xc1, 0xb6, 0x40, 0xde, 0x66, 0x7b, 0x66, 0x8e, 0x92, 0xa3, 0x70, 0x38, 0xa7, 0x25, 0x73, 0xb4, + 0x64, 0x8d, 0xfa, 0x3d, 0x6a, 0xaf, 0x57, 0xbd, 0x63, 0xb5, 0x3f, 0x64, 0x08, 0x68, 0xe7, 0x49, + 0x79, 0xbc, 0x43, 0x69, 0xd2, 0xb4, 0x78, 0x75, 0x3b, 0x2e, 0x04, 0xe4, 0x4d, 0x56, 0x51, 0xb1, + 0x54, 0x12, 0x07, 0x23, 0x72, 0x16, 0xc8, 0x59, 0xde, 0xf4, 0xd6, 0xc2, 0x4b, 0x56, 0xda, 0x94, + 0x68, 0xff, 0x27, 0x97, 0x48, 0x77, 0xf5, 0x12, 0xcc, 0xdb, 0x06, 0xf8, 0x29, 0xcb, 0xcf, 0xa4, + 0x06, 0xb4, 0x8b, 0x94, 0xac, 0xa7, 0x27, 0x1f, 0xa4, 0x06, 0xcf, 0x80, 0xd7, 0x57, 0x5f, 0x4b, + 0x61, 0x2d, 0x96, 0xc2, 0xfa, 0x59, 0x0a, 0xeb, 0x63, 0x25, 0x32, 0x8b, 0x95, 0xc8, 0x7c, 0xaf, + 0x44, 0xe6, 0xf1, 0x28, 0x08, 0xf5, 0xeb, 0xd4, 0x77, 0x86, 0x32, 0x72, 0x93, 0x03, 0x30, 0xcf, + 0x09, 0x3e, 0xbf, 0xb9, 0xef, 0xe6, 0x1a, 0xfc, 0x02, 0x1d, 0xc0, 0xf9, 0x6f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x87, 0x02, 0xbb, 0xdc, 0x5e, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -236,8 +235,8 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x2a } } - if m.GroupPolicyAccountSeq != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.GroupPolicyAccountSeq)) + if m.GroupPolicySeq != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.GroupPolicySeq)) i-- dAtA[i] = 0x20 } @@ -309,8 +308,8 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if m.GroupPolicyAccountSeq != 0 { - n += 1 + sovGenesis(uint64(m.GroupPolicyAccountSeq)) + if m.GroupPolicySeq != 0 { + n += 1 + sovGenesis(uint64(m.GroupPolicySeq)) } if len(m.GroupPolicies) > 0 { for _, e := range m.GroupPolicies { @@ -460,9 +459,9 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupPolicyAccountSeq", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GroupPolicySeq", wireType) } - m.GroupPolicyAccountSeq = 0 + m.GroupPolicySeq = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -472,7 +471,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.GroupPolicyAccountSeq |= uint64(b&0x7F) << shift + m.GroupPolicySeq |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/group/genesis_test.go b/x/group/genesis_test.go index 536e4a6f13..c827f726c2 100644 --- a/x/group/genesis_test.go +++ b/x/group/genesis_test.go @@ -88,7 +88,7 @@ func TestGenesisStateValidate(t *testing.T) { GroupSeq: 2, Groups: []*GroupInfo{{GroupId: 1, Admin: accAddr.String(), Metadata: []byte("1"), Version: 1, TotalWeight: "1"}, {GroupId: 2, Admin: accAddr.String(), Metadata: []byte("2"), Version: 2, TotalWeight: "2"}}, GroupMembers: []*GroupMember{{GroupId: 1, Member: &Member{Address: memberAddr.String(), Weight: "1", Metadata: []byte("member metadata")}}, {GroupId: 2, Member: &Member{Address: memberAddr.String(), Weight: "2", Metadata: []byte("member metadata")}}}, - GroupPolicyAccountSeq: 1, + GroupPolicySeq: 1, GroupPolicies: []*GroupPolicyInfo{groupPolicy}, ProposalSeq: 1, Proposals: []*Proposal{proposal}, diff --git a/x/group/keeper/genesis.go b/x/group/keeper/genesis.go index 3553c5c79d..311809de39 100644 --- a/x/group/keeper/genesis.go +++ b/x/group/keeper/genesis.go @@ -27,7 +27,7 @@ func (k Keeper) InitGenesis(ctx types.Context, cdc codec.JSONCodec, data json.Ra panic(errors.Wrap(err, "group policies")) } - if err := k.groupPolicySeq.InitVal(ctx.KVStore(k.key), genesisState.GroupPolicyAccountSeq); err != nil { + if err := k.groupPolicySeq.InitVal(ctx.KVStore(k.key), genesisState.GroupPolicySeq); err != nil { panic(errors.Wrap(err, "group policy account seq")) } @@ -68,7 +68,7 @@ func (k Keeper) ExportGenesis(ctx types.Context, cdc codec.JSONCodec) *group.Gen panic(errors.Wrap(err, "group policies")) } genesisState.GroupPolicies = groupPolicies - genesisState.GroupPolicyAccountSeq = k.groupPolicySeq.CurVal(ctx.KVStore(k.key)) + genesisState.GroupPolicySeq = k.groupPolicySeq.CurVal(ctx.KVStore(k.key)) var proposals []*group.Proposal proposalSeq, err := k.proposalTable.Export(ctx.KVStore(k.key), &proposals) diff --git a/x/group/keeper/genesis_test.go b/x/group/keeper/genesis_test.go index 59644ea987..1ca37e5669 100644 --- a/x/group/keeper/genesis_test.go +++ b/x/group/keeper/genesis_test.go @@ -109,7 +109,7 @@ func (s *GenesisTestSuite) TestInitExportGenesis() { GroupSeq: 2, Groups: []*group.GroupInfo{{GroupId: 1, Admin: accAddr.String(), Metadata: []byte("1"), Version: 1, TotalWeight: "1"}, {GroupId: 2, Admin: accAddr.String(), Metadata: []byte("2"), Version: 2, TotalWeight: "2"}}, GroupMembers: []*group.GroupMember{{GroupId: 1, Member: &group.Member{Address: memberAddr.String(), Weight: "1", Metadata: []byte("member metadata")}}, {GroupId: 2, Member: &group.Member{Address: memberAddr.String(), Weight: "2", Metadata: []byte("member metadata")}}}, - GroupPolicyAccountSeq: 1, + GroupPolicySeq: 1, GroupPolicies: []*group.GroupPolicyInfo{groupPolicy}, ProposalSeq: 1, Proposals: []*group.Proposal{proposal}, @@ -189,7 +189,7 @@ func (s *GenesisTestSuite) TestInitExportGenesis() { s.Require().Equal(genesisState.Votes, exportedGenesisState.Votes) s.Require().Equal(genesisState.GroupSeq, exportedGenesisState.GroupSeq) - s.Require().Equal(genesisState.GroupPolicyAccountSeq, exportedGenesisState.GroupPolicyAccountSeq) + s.Require().Equal(genesisState.GroupPolicySeq, exportedGenesisState.GroupPolicySeq) s.Require().Equal(genesisState.ProposalSeq, exportedGenesisState.ProposalSeq) } diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index e428ad45e3..255dd7790b 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -212,3 +212,8 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddle func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", group.ModuleName)) } + +// GetGroupSequence returns the current value of the group table sequence +func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { + return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) +} diff --git a/x/group/keeper/msg_server.go b/x/group/keeper/msg_server.go index 745dbb271b..aedb88e7aa 100644 --- a/x/group/keeper/msg_server.go +++ b/x/group/keeper/msg_server.go @@ -116,7 +116,7 @@ func (k Keeper) UpdateGroupMembers(goCtx context.Context, req *group.MsgUpdateGr }, } - // Checking if the group member is already part of the + // Checking if the group member is already part of the group var found bool var prevGroupMember group.GroupMember switch err := k.groupMemberTable.GetOne(ctx.KVStore(k.key), orm.PrimaryKey(&groupMember), &prevGroupMember); { diff --git a/x/group/module/module.go b/x/group/module/module.go index 8601fb67fa..78102cfe9f 100644 --- a/x/group/module/module.go +++ b/x/group/module/module.go @@ -19,7 +19,8 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/group" "github.com/cosmos/cosmos-sdk/x/group/client/cli" - groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/cosmos/cosmos-sdk/x/group/simulation" ) var ( @@ -30,19 +31,19 @@ var ( type AppModule struct { AppModuleBasic - keeper groupkeeper.Keeper - BankKeeper group.BankKeeper - AccountKeeper group.AccountKeeper - registry cdctypes.InterfaceRegistry + keeper keeper.Keeper + bankKeeper group.BankKeeper + accKeeper group.AccountKeeper + registry cdctypes.InterfaceRegistry } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper groupkeeper.Keeper, ak group.AccountKeeper, bk group.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule { +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak group.AccountKeeper, bk group.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, - BankKeeper: bk, - AccountKeeper: ak, + bankKeeper: bk, + accKeeper: ak, registry: registry, } } @@ -107,7 +108,7 @@ func (AppModule) Name() string { // RegisterInvariants does nothing, there are no invariants to enforce func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { - groupkeeper.RegisterInvariants(ir, am.keeper) + keeper.RegisterInvariants(ir, am.keeper) } // Deprecated: Route returns the message routing key for the group module. @@ -164,6 +165,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.Val // GenerateGenesisState creates a randomized GenState of the group module. func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) } // ProposalContents returns all the group content functions used to @@ -179,10 +181,13 @@ func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { // RegisterStoreDecoder registers a decoder for group module's types func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + sdr[group.StoreKey] = simulation.NewDecodeStore(am.cdc) } // WeightedOperations returns the all the gov module operations with their respective weights. func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - // TODO - return nil + return simulation.WeightedOperations( + simState.AppParams, simState.Cdc, + am.accKeeper, am.bankKeeper, am.keeper, am.cdc, + ) } diff --git a/x/group/msgs.go b/x/group/msgs.go index 622203cba3..c76209250a 100644 --- a/x/group/msgs.go +++ b/x/group/msgs.go @@ -13,28 +13,13 @@ import ( "github.com/cosmos/cosmos-sdk/x/group/internal/math" ) -// Group message types and routes -const ( - TypeMsgCreateGroup = "create_group" - TypeMsgUpdateGroupAdmin = "update_group_admin" - TypeMsgUpdateGroupMetadata = "update_group_metadata" - TypeMsgUpdateGroupMembers = "update_group_members" - TypeMsgCreateGroupPolicy = "create_group_policy" - TypeMsgUpdateGroupPolicyAdmin = "update_group_policy_admin" - TypeMsgUpdateGroupPolicyDecisionPolicy = "update_group_policy_decision_policy" - TypeMsgUpdateGroupPolicyMetadata = "update_group_policy_metadata" - TypeMsgCreateProposal = "create_proposal" - TypeMsgVote = "vote" - TypeMsgExec = "exec" -) - var _ sdk.Msg = &MsgCreateGroup{} // Route Implements Msg. -func (m MsgCreateGroup) Route() string { return RouterKey } +func (m MsgCreateGroup) Route() string { return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgCreateGroup) Type() string { return TypeMsgCreateGroup } +func (m MsgCreateGroup) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgCreateGroup) GetSignBytes() []byte { @@ -100,11 +85,11 @@ var _ sdk.Msg = &MsgUpdateGroupAdmin{} // Route Implements Msg. func (m MsgUpdateGroupAdmin) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgUpdateGroupAdmin) Type() string { return TypeMsgUpdateGroupAdmin } +func (m MsgUpdateGroupAdmin) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgUpdateGroupAdmin) GetSignBytes() []byte { @@ -150,11 +135,11 @@ var _ sdk.Msg = &MsgUpdateGroupMetadata{} // Route Implements Msg. func (m MsgUpdateGroupMetadata) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgUpdateGroupMetadata) Type() string { return TypeMsgUpdateGroupMetadata } +func (m MsgUpdateGroupMetadata) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgUpdateGroupMetadata) GetSignBytes() []byte { @@ -192,11 +177,11 @@ var _ sdk.Msg = &MsgUpdateGroupMembers{} // Route Implements Msg. func (m MsgUpdateGroupMembers) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgUpdateGroupMembers) Type() string { return TypeMsgUpdateGroupMembers } +func (m MsgUpdateGroupMembers) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgUpdateGroupMembers) GetSignBytes() []byte { @@ -243,11 +228,11 @@ var _ sdk.Msg = &MsgCreateGroupPolicy{} // Route Implements Msg. func (m MsgCreateGroupPolicy) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgCreateGroupPolicy) Type() string { return TypeMsgCreateGroupPolicy } +func (m MsgCreateGroupPolicy) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgCreateGroupPolicy) GetSignBytes() []byte { @@ -288,11 +273,11 @@ var _ sdk.Msg = &MsgUpdateGroupPolicyAdmin{} // Route Implements Msg. func (m MsgUpdateGroupPolicyAdmin) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgUpdateGroupPolicyAdmin) Type() string { return TypeMsgUpdateGroupPolicyAdmin } +func (m MsgUpdateGroupPolicyAdmin) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgUpdateGroupPolicyAdmin) GetSignBytes() []byte { @@ -361,12 +346,12 @@ func (m *MsgUpdateGroupPolicyDecisionPolicy) SetDecisionPolicy(decisionPolicy De // Route Implements Msg. func (m MsgUpdateGroupPolicyDecisionPolicy) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. func (m MsgUpdateGroupPolicyDecisionPolicy) Type() string { - return TypeMsgUpdateGroupPolicyDecisionPolicy + return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. @@ -425,11 +410,11 @@ var _ sdk.Msg = &MsgUpdateGroupPolicyMetadata{} // Route Implements Msg. func (m MsgUpdateGroupPolicyMetadata) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgUpdateGroupPolicyMetadata) Type() string { return TypeMsgUpdateGroupPolicyMetadata } +func (m MsgUpdateGroupPolicyMetadata) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgUpdateGroupPolicyMetadata) GetSignBytes() []byte { @@ -535,11 +520,11 @@ func NewMsgCreateProposalRequest(address string, proposers []string, msgs []sdk. // Route Implements Msg. func (m MsgCreateProposal) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgCreateProposal) Type() string { return TypeMsgCreateProposal } +func (m MsgCreateProposal) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgCreateProposal) GetSignBytes() []byte { @@ -618,11 +603,11 @@ var _ sdk.Msg = &MsgVote{} // Route Implements Msg. func (m MsgVote) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgVote) Type() string { return TypeMsgVote } +func (m MsgVote) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgVote) GetSignBytes() []byte { @@ -660,11 +645,11 @@ var _ sdk.Msg = &MsgExec{} // Route Implements Msg. func (m MsgExec) Route() string { - return RouterKey + return sdk.MsgTypeURL(&m) } // Type Implements Msg. -func (m MsgExec) Type() string { return TypeMsgExec } +func (m MsgExec) Type() string { return sdk.MsgTypeURL(&m) } // GetSignBytes Implements Msg. func (m MsgExec) GetSignBytes() []byte { diff --git a/x/group/msgs_test.go b/x/group/msgs_test.go index 83ebd9af79..1d47eb9ba4 100644 --- a/x/group/msgs_test.go +++ b/x/group/msgs_test.go @@ -146,7 +146,7 @@ func TestMsgCreateGroup(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, tc.msg.Type(), group.TypeMsgCreateGroup) + require.Equal(t, tc.msg.Type(), sdk.MsgTypeURL(&group.MsgCreateGroup{})) } }) } @@ -217,7 +217,7 @@ func TestMsgUpdateGroupAdmin(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupAdmin) + require.Equal(t, tc.msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupAdmin{})) } }) } @@ -267,7 +267,7 @@ func TestMsgUpdateGroupMetadata(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupMetadata) + require.Equal(t, tc.msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupMetadata{})) } }) } @@ -347,7 +347,7 @@ func TestMsgUpdateGroupMembers(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupMembers) + require.Equal(t, tc.msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupMembers{})) } }) } @@ -414,7 +414,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgCreateGroupPolicy) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgCreateGroupPolicy{})) } }) } @@ -484,7 +484,7 @@ func TestMsgUpdateGroupPolicyDecisionPolicy(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyDecisionPolicy) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyDecisionPolicy{})) } }) } @@ -556,7 +556,7 @@ func TestMsgUpdateGroupPolicyAdmin(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyAdmin) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyAdmin{})) } }) } @@ -607,7 +607,7 @@ func TestMsgUpdateGroupPolicyMetadata(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyMetadata) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyMetadata{})) } }) } @@ -656,7 +656,7 @@ func TestMsgCreateProposal(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgCreateProposal) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgCreateProposal{})) } }) } @@ -715,7 +715,7 @@ func TestMsgVote(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgVote) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgVote{})) } }) } @@ -763,7 +763,7 @@ func TestMsgExec(t *testing.T) { require.Contains(t, err.Error(), tc.errMsg) } else { require.NoError(t, err) - require.Equal(t, msg.Type(), group.TypeMsgExec) + require.Equal(t, msg.Type(), sdk.MsgTypeURL(&group.MsgExec{})) } }) } diff --git a/x/group/simulation/decoder.go b/x/group/simulation/decoder.go new file mode 100644 index 0000000000..aea2e9e1d7 --- /dev/null +++ b/x/group/simulation/decoder.go @@ -0,0 +1,57 @@ +package simulation + +import ( + "bytes" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/cosmos-sdk/x/group/keeper" +) + +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's +// Value to the corresponding group type. +func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { + switch { + case bytes.Equal(kvA.Key[:1], []byte{keeper.GroupTablePrefix}): + var groupA, groupB group.GroupInfo + + cdc.MustUnmarshal(kvA.Value, &groupA) + cdc.MustUnmarshal(kvB.Value, &groupB) + + return fmt.Sprintf("%v\n%v", groupA, groupB) + case bytes.Equal(kvA.Key[:1], []byte{keeper.GroupMemberTablePrefix}): + var memberA, memberB group.GroupMember + + cdc.MustUnmarshal(kvA.Value, &memberA) + cdc.MustUnmarshal(kvB.Value, &memberB) + + return fmt.Sprintf("%v\n%v", memberA, memberB) + case bytes.Equal(kvA.Key[:1], []byte{keeper.GroupPolicyTablePrefix}): + var accA, accB group.GroupPolicyInfo + + cdc.MustUnmarshal(kvA.Value, &accA) + cdc.MustUnmarshal(kvB.Value, &accB) + + return fmt.Sprintf("%v\n%v", accA, accB) + case bytes.Equal(kvA.Key[:1], []byte{keeper.ProposalTablePrefix}): + var propA, propB group.Proposal + + cdc.MustUnmarshal(kvA.Value, &propA) + cdc.MustUnmarshal(kvB.Value, &propB) + + return fmt.Sprintf("%v\n%v", propA, propB) + case bytes.Equal(kvA.Key[:1], []byte{keeper.VoteTablePrefix}): + var voteA, voteB group.Vote + + cdc.MustUnmarshal(kvA.Value, &voteA) + cdc.MustUnmarshal(kvB.Value, &voteB) + + return fmt.Sprintf("%v\n%v", voteA, voteB) + default: + panic(fmt.Sprintf("invalid group key %X", kvA.Key)) + } + } +} diff --git a/x/group/simulation/decoder_test.go b/x/group/simulation/decoder_test.go new file mode 100644 index 0000000000..95aff5ef16 --- /dev/null +++ b/x/group/simulation/decoder_test.go @@ -0,0 +1,80 @@ +package simulation_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/cosmos-sdk/x/group/internal/orm" + "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/cosmos/cosmos-sdk/x/group/simulation" +) + +func TestDecodeStore(t *testing.T) { + cdc := simapp.MakeTestEncodingConfig().Codec + dec := simulation.NewDecodeStore(cdc) + + g := group.GroupInfo{GroupId: 1} + groupBz, err := cdc.Marshal(&g) + require.NoError(t, err) + + _, _, addr := testdata.KeyTestPubAddr() + member := group.GroupMember{GroupId: 1, Member: &group.Member{ + Address: addr.String(), + }} + memberBz, err := cdc.Marshal(&member) + require.NoError(t, err) + + _, _, accAddr := testdata.KeyTestPubAddr() + acc := group.GroupPolicyInfo{Address: accAddr.String()} + accBz, err := cdc.Marshal(&acc) + require.NoError(t, err) + + proposal := group.Proposal{ProposalId: 1} + proposalBz, err := cdc.Marshal(&proposal) + require.NoError(t, err) + + vote := group.Vote{Voter: addr.String(), ProposalId: 1} + voteBz, err := cdc.Marshal(&vote) + require.NoError(t, err) + + kvPairs := kv.Pairs{ + Pairs: []kv.Pair{ + {Key: append([]byte{keeper.GroupTablePrefix}, orm.PrimaryKey(&g)...), Value: groupBz}, + {Key: append([]byte{keeper.GroupMemberTablePrefix}, orm.PrimaryKey(&member)...), Value: memberBz}, + {Key: append([]byte{keeper.GroupPolicyTablePrefix}, orm.PrimaryKey(&acc)...), Value: accBz}, + {Key: append([]byte{keeper.ProposalTablePrefix}, orm.PrimaryKey(&proposal)...), Value: proposalBz}, + {Key: append([]byte{keeper.VoteTablePrefix}, orm.PrimaryKey(&vote)...), Value: voteBz}, + {Key: []byte{0x99}, Value: []byte{0x99}}, + }, + } + + tests := []struct { + name string + expectErr bool + expectedLog string + }{ + {"Group", false, fmt.Sprintf("%v\n%v", g, g)}, + {"GroupMember", false, fmt.Sprintf("%v\n%v", member, member)}, + {"GroupPolicy", false, fmt.Sprintf("%v\n%v", acc, acc)}, + {"Proposal", false, fmt.Sprintf("%v\n%v", proposal, proposal)}, + {"Vote", false, fmt.Sprintf("%v\n%v", vote, vote)}, + {"other", true, ""}, + } + + for i, tt := range tests { + i, tt := i, tt + t.Run(tt.name, func(t *testing.T) { + if tt.expectErr { + require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) + } else { + require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) + } + }) + } +} diff --git a/x/group/simulation/genesis.go b/x/group/simulation/genesis.go new file mode 100644 index 0000000000..20e59e6dd5 --- /dev/null +++ b/x/group/simulation/genesis.go @@ -0,0 +1,199 @@ +package simulation + +import ( + "math/rand" + "time" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/cosmos/cosmos-sdk/x/group" +) + +const ( + GroupInfo = "group-info" + GroupMembers = "group-members" + GroupPolicyInfo = "group-policy-info" + GroupProposals = "group-proposals" + GroupVote = "group-vote" +) + +func getGroups(r *rand.Rand, accounts []simtypes.Account) []*group.GroupInfo { + groups := make([]*group.GroupInfo, 3) + for i := 0; i < 3; i++ { + acc, _ := simtypes.RandomAcc(r, accounts) + groups[i] = &group.GroupInfo{ + GroupId: uint64(i + 1), + Admin: acc.Address.String(), + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + Version: 1, + TotalWeight: "10", + } + } + return groups +} + +func getGroupMembers(r *rand.Rand, accounts []simtypes.Account) []*group.GroupMember { + groupMembers := make([]*group.GroupMember, 3) + for i := 0; i < 3; i++ { + acc, _ := simtypes.RandomAcc(r, accounts) + groupMembers[i] = &group.GroupMember{ + GroupId: uint64(i + 1), + Member: &group.Member{ + Address: acc.Address.String(), + Weight: "10", + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + }, + } + } + return groupMembers +} + +func getGroupPolicies(r *rand.Rand, simState *module.SimulationState) []*group.GroupPolicyInfo { + groupPolicies := make([]*group.GroupPolicyInfo, 3) + for i := 0; i < 3; i++ { + acc, _ := simtypes.RandomAcc(r, simState.Accounts) + any, err := codectypes.NewAnyWithValue(group.NewThresholdDecisionPolicy("10", time.Second*time.Duration(1))) + if err != nil { + panic(err) + } + groupPolicies[i] = &group.GroupPolicyInfo{ + GroupId: uint64(i + 1), + Admin: acc.Address.String(), + Address: acc.Address.String(), + Version: 1, + DecisionPolicy: any, + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + } + } + return groupPolicies +} + +func getProposals(r *rand.Rand, simState *module.SimulationState) []*group.Proposal { + proposals := make([]*group.Proposal, 3) + proposers := []string{simState.Accounts[0].Address.String(), simState.Accounts[1].Address.String()} + for i := 0; i < 3; i++ { + from, _ := simtypes.RandomAcc(r, simState.Accounts) + to, _ := simtypes.RandomAcc(r, simState.Accounts) + fromAddr := from.Address.String() + + submittedAt := time.Unix(0, 0) + timeout := submittedAt.Add(time.Second * 1000).UTC() + + proposal := &group.Proposal{ + ProposalId: uint64(i + 1), + Proposers: proposers, + Address: fromAddr, + GroupVersion: uint64(i + 1), + GroupPolicyVersion: uint64(i + 1), + Status: group.ProposalStatusSubmitted, + Result: group.ProposalResultAccepted, + VoteState: group.Tally{ + YesCount: "1", + NoCount: "1", + AbstainCount: "1", + VetoCount: "0", + }, + ExecutorResult: group.ProposalExecutorResultNotRun, + Metadata: []byte(simtypes.RandStringOfLength(r, 50)), + SubmittedAt: submittedAt, + Timeout: timeout, + } + err := proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{ + FromAddress: fromAddr, + ToAddress: to.Address.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("test", 10)), + }}) + if err != nil { + panic(err) + } + + proposals[i] = proposal + } + + return proposals +} + +func getVotes(r *rand.Rand, simState *module.SimulationState) []*group.Vote { + votes := make([]*group.Vote, 3) + + for i := 0; i < 3; i++ { + votes[i] = &group.Vote{ + ProposalId: uint64(i + 1), + Voter: simState.Accounts[i].Address.String(), + Choice: getVoteChoice(i), + Metadata: []byte(simtypes.RandStringOfLength(r, 50)), + SubmittedAt: time.Unix(0, 0), + } + } + + return votes +} + +func getVoteChoice(index int) group.Choice { + switch index { + case 0: + return group.Choice_CHOICE_YES + case 1: + return group.Choice_CHOICE_NO + case 2: + return group.Choice_CHOICE_ABSTAIN + default: + return group.Choice_CHOICE_VETO + } +} + +// RandomizedGenState generates a random GenesisState for the group module. +func RandomizedGenState(simState *module.SimulationState) { + + // groups + var groups []*group.GroupInfo + simState.AppParams.GetOrGenerate( + simState.Cdc, GroupInfo, &groups, simState.Rand, + func(r *rand.Rand) { groups = getGroups(r, simState.Accounts) }, + ) + + // group members + var members []*group.GroupMember + simState.AppParams.GetOrGenerate( + simState.Cdc, GroupMembers, &members, simState.Rand, + func(r *rand.Rand) { members = getGroupMembers(r, simState.Accounts) }, + ) + + // group accounts + var groupPolicies []*group.GroupPolicyInfo + simState.AppParams.GetOrGenerate( + simState.Cdc, GroupPolicyInfo, &groupPolicies, simState.Rand, + func(r *rand.Rand) { groupPolicies = getGroupPolicies(r, simState) }, + ) + + // proposals + var proposals []*group.Proposal + simState.AppParams.GetOrGenerate( + simState.Cdc, GroupProposals, &proposals, simState.Rand, + func(r *rand.Rand) { proposals = getProposals(r, simState) }, + ) + + // votes + var votes []*group.Vote + simState.AppParams.GetOrGenerate( + simState.Cdc, GroupVote, &votes, simState.Rand, + func(r *rand.Rand) { votes = getVotes(r, simState) }, + ) + + groupGenesis := group.GenesisState{ + GroupSeq: 3, + Groups: groups, + GroupMembers: members, + GroupPolicySeq: 3, + GroupPolicies: groupPolicies, + ProposalSeq: 3, + Proposals: proposals, + Votes: votes, + } + + simState.GenState[group.ModuleName] = simState.Cdc.MustMarshalJSON(&groupGenesis) +} diff --git a/x/group/simulation/genesis_test.go b/x/group/simulation/genesis_test.go new file mode 100644 index 0000000000..cf7b1cda67 --- /dev/null +++ b/x/group/simulation/genesis_test.go @@ -0,0 +1,46 @@ +package simulation_test + +import ( + "encoding/json" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/cosmos-sdk/x/group/simulation" +) + +func TestRandomizedGenState(t *testing.T) { + app := simapp.Setup(t, false) + + s := rand.NewSource(1) + r := rand.New(s) + + simState := module.SimulationState{ + AppParams: make(simtypes.AppParams), + Cdc: app.AppCodec(), + Rand: r, + NumBonded: 3, + Accounts: simtypes.RandomAccounts(r, 3), + InitialStake: 1000, + GenState: make(map[string]json.RawMessage), + } + + simulation.RandomizedGenState(&simState) + var groupGenesis group.GenesisState + simState.Cdc.MustUnmarshalJSON(simState.GenState[group.ModuleName], &groupGenesis) + + require.Equal(t, int(groupGenesis.GroupSeq), len(simState.Accounts)) + require.Len(t, groupGenesis.Groups, len(simState.Accounts)) + require.Len(t, groupGenesis.GroupMembers, len(simState.Accounts)) + require.Equal(t, int(groupGenesis.GroupPolicySeq), len(simState.Accounts)) + require.Len(t, groupGenesis.GroupPolicies, len(simState.Accounts)) + require.Equal(t, int(groupGenesis.ProposalSeq), len(simState.Accounts)) + require.Len(t, groupGenesis.Proposals, len(simState.Accounts)) + require.Len(t, groupGenesis.Votes, len(simState.Accounts)) + +} diff --git a/x/group/simulation/operations.go b/x/group/simulation/operations.go new file mode 100644 index 0000000000..9fd304e2b7 --- /dev/null +++ b/x/group/simulation/operations.go @@ -0,0 +1,999 @@ +package simulation + +import ( + "context" + "fmt" + "math/rand" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/simapp/helpers" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/cosmos/cosmos-sdk/x/group" +) + +var initialGroupID = uint64(100000000000000) + +// group message types +var ( + TypeMsgCreateGroup = sdk.MsgTypeURL(&group.MsgCreateGroup{}) + TypeMsgUpdateGroupMembers = sdk.MsgTypeURL(&group.MsgUpdateGroupMembers{}) + TypeMsgUpdateGroupAdmin = sdk.MsgTypeURL(&group.MsgUpdateGroupAdmin{}) + TypeMsgUpdateGroupMetadata = sdk.MsgTypeURL(&group.MsgUpdateGroupMetadata{}) + TypeMsgCreateGroupPolicy = sdk.MsgTypeURL(&group.MsgCreateGroupPolicy{}) + TypeMsgUpdateGroupPolicyAdmin = sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyAdmin{}) + TypeMsgUpdateGroupPolicyDecisionPolicy = sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyDecisionPolicy{}) + TypeMsgUpdateGroupPolicyMetadata = sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyMetadata{}) + TypeMsgCreateProposal = sdk.MsgTypeURL(&group.MsgCreateProposal{}) + TypeMsgVote = sdk.MsgTypeURL(&group.MsgVote{}) + TypeMsgExec = sdk.MsgTypeURL(&group.MsgExec{}) +) + +// Simulation operation weights constants +const ( + OpMsgCreateGroup = "op_weight_msg_create_group" + OpMsgUpdateGroupAdmin = "op_weight_msg_update_group_admin" + OpMsgUpdateGroupMetadata = "op_wieght_msg_update_group_metadata" + OpMsgUpdateGroupMembers = "op_weight_msg_update_group_members" + OpMsgCreateGroupPolicy = "op_weight_msg_create_group_account" + OpMsgUpdateGroupPolicyAdmin = "op_weight_msg_update_group_account_admin" + OpMsgUpdateGroupPolicyDecisionPolicy = "op_weight_msg_update_group_account_decision_policy" + OpMsgUpdateGroupPolicyMetaData = "op_weight_msg_update_group_account_metadata" + OpMsgCreateProposal = "op_weight_msg_create_proposal" + OpMsgVote = "op_weight_msg_vote" + OpMsgExec = "ops_weight_msg_exec" +) + +// If update group or group account txn's executed, `SimulateMsgVote` & `SimulateMsgExec` txn's returns `noOp`. +// That's why we have less weight for update group & group-account txn's. +const ( + WeightMsgCreateGroup = 100 + WeightMsgCreateGroupPolicy = 100 + WeightMsgCreateProposal = 90 + WeightMsgVote = 90 + WeightMsgExec = 90 + WeightMsgUpdateGroupMetadata = 5 + WeightMsgUpdateGroupAdmin = 5 + WeightMsgUpdateGroupMembers = 5 + WeightMsgUpdateGroupPolicyAdmin = 5 + WeightMsgUpdateGroupPolicyDecisionPolicy = 5 + WeightMsgUpdateGroupPolicyMetadata = 5 +) + +const GroupMemberWeight = 40 + +// WeightedOperations returns all the operations from the module with their respective weights +func WeightedOperations( + appParams simtypes.AppParams, cdc codec.JSONCodec, ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper, appCdc cdctypes.AnyUnpacker) simulation.WeightedOperations { + var ( + weightMsgCreateGroup int + weightMsgUpdateGroupAdmin int + weightMsgUpdateGroupMetadata int + weightMsgUpdateGroupMembers int + weightMsgCreateGroupPolicy int + weightMsgUpdateGroupPolicyAdmin int + weightMsgUpdateGroupPolicyDecisionPolicy int + weightMsgUpdateGroupPolicyMetadata int + weightMsgCreateProposal int + weightMsgVote int + weightMsgExec int + ) + + appParams.GetOrGenerate(cdc, OpMsgCreateGroup, &weightMsgCreateGroup, nil, + func(_ *rand.Rand) { + weightMsgCreateGroup = WeightMsgCreateGroup + }, + ) + appParams.GetOrGenerate(cdc, OpMsgCreateGroupPolicy, &weightMsgCreateGroupPolicy, nil, + func(_ *rand.Rand) { + weightMsgCreateGroupPolicy = WeightMsgCreateGroupPolicy + }, + ) + appParams.GetOrGenerate(cdc, OpMsgCreateProposal, &weightMsgCreateProposal, nil, + func(_ *rand.Rand) { + weightMsgCreateProposal = WeightMsgCreateProposal + }, + ) + appParams.GetOrGenerate(cdc, OpMsgVote, &weightMsgVote, nil, + func(_ *rand.Rand) { + weightMsgVote = WeightMsgVote + }, + ) + appParams.GetOrGenerate(cdc, OpMsgExec, &weightMsgExec, nil, + func(_ *rand.Rand) { + weightMsgExec = WeightMsgExec + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupMetadata, &weightMsgUpdateGroupMetadata, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupMetadata = WeightMsgUpdateGroupMetadata + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupAdmin, &weightMsgUpdateGroupAdmin, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupAdmin = WeightMsgUpdateGroupAdmin + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupMembers, &weightMsgUpdateGroupMembers, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupMembers = WeightMsgUpdateGroupMembers + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupPolicyAdmin, &weightMsgUpdateGroupPolicyAdmin, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupPolicyAdmin = WeightMsgUpdateGroupPolicyAdmin + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupPolicyDecisionPolicy, &weightMsgUpdateGroupPolicyDecisionPolicy, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupPolicyDecisionPolicy = WeightMsgUpdateGroupPolicyDecisionPolicy + }, + ) + appParams.GetOrGenerate(cdc, OpMsgUpdateGroupPolicyMetaData, &weightMsgUpdateGroupPolicyMetadata, nil, + func(_ *rand.Rand) { + weightMsgUpdateGroupPolicyMetadata = WeightMsgUpdateGroupPolicyMetadata + }, + ) + + return simulation.WeightedOperations{ + simulation.NewWeightedOperation( + weightMsgCreateGroup, + SimulateMsgCreateGroup(ak, bk), + ), + simulation.NewWeightedOperation( + weightMsgCreateGroupPolicy, + SimulateMsgCreateGroupPolicy(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgCreateProposal, + SimulateMsgCreateProposal(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgVote, + SimulateMsgVote(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgExec, + SimulateMsgExec(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupMetadata, + SimulateMsgUpdateGroupMetadata(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupAdmin, + SimulateMsgUpdateGroupAdmin(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupMembers, + SimulateMsgUpdateGroupMembers(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupPolicyAdmin, + SimulateMsgUpdateGroupPolicyAdmin(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupPolicyDecisionPolicy, + SimulateMsgUpdateGroupPolicyDecisionPolicy(ak, bk, k), + ), + simulation.NewWeightedOperation( + weightMsgUpdateGroupPolicyMetadata, + SimulateMsgUpdateGroupPolicyMetadata(ak, bk, k), + ), + } +} + +// SimulateMsgCreateGroup generates a MsgCreateGroup with random values +func SimulateMsgCreateGroup(ak group.AccountKeeper, bk group.BankKeeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + acc, _ := simtypes.RandomAcc(r, accounts) + account := ak.GetAccount(ctx, acc.Address) + accAddr := acc.Address.String() + + spendableCoins := bk.SpendableCoins(ctx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, ctx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroup, "fee error"), nil, err + } + + members := []group.Member{ + { + Address: accAddr, + Weight: fmt.Sprintf("%d", GroupMemberWeight), + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + }, + } + + msg := &group.MsgCreateGroup{Admin: accAddr, Members: members, Metadata: []byte(simtypes.RandStringOfLength(r, 10))} + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroup, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "", nil), nil, err + } +} + +// SimulateMsgCreateGroupPolicy generates a NewMsgCreateGroupPolicy with random values +func SimulateMsgCreateGroupPolicy(ak group.AccountKeeper, bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + groupInfo, acc, account, err := randomGroup(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroupPolicy, ""), nil, err + } + if groupInfo == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroupPolicy, ""), nil, nil + } + groupID := groupInfo.GroupId + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroupPolicy, "fee error"), nil, err + } + + msg, err := group.NewMsgCreateGroupPolicy( + acc.Address, + groupID, + []byte(simtypes.RandStringOfLength(r, 10)), + &group.ThresholdDecisionPolicy{ + Threshold: "20", + Timeout: time.Second * time.Duration(30*24*60*60), + }, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroupPolicy, err.Error()), nil, err + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateGroupPolicy, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + fmt.Printf("ERR DELIVER %v\n", err) + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "", nil), nil, err + } +} + +// SimulateMsgCreateProposal generates a NewMsgCreateProposal with random values +func SimulateMsgCreateProposal(ak group.AccountKeeper, bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + g, groupPolicy, _, _, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, ""), nil, err + } + if g == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, "no group found"), nil, nil + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, "no group policy found"), nil, nil + } + groupID := g.GroupId + groupPolicyAddr := groupPolicy.Address + + // Return a no-op if we know the proposal cannot be created + policy := groupPolicy.GetDecisionPolicy() + err = policy.Validate(*g) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, ""), nil, nil + } + + // Pick a random member from the group + ctx := sdk.WrapSDKContext(sdkCtx) + acc, account, err := randomMember(r, k, ak, ctx, accounts, groupID) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, ""), nil, err + } + if account == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, "no group member found"), nil, nil + } + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, "fee error"), nil, err + } + + msg := group.MsgCreateProposal{ + Address: groupPolicyAddr, + Proposers: []string{acc.Address.String()}, + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgCreateProposal, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// SimulateMsgUpdateGroupAdmin generates a MsgUpdateGroupAdmin with random values +func SimulateMsgUpdateGroupAdmin(ak group.AccountKeeper, bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + groupInfo, acc, account, err := randomGroup(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupAdmin, ""), nil, err + } + if groupInfo == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupAdmin, ""), nil, nil + } + groupID := groupInfo.GroupId + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupAdmin, "fee error"), nil, err + } + + if len(accounts) == 1 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupAdmin, "can't set a new admin with only one account"), nil, nil + } + newAdmin, _ := simtypes.RandomAcc(r, accounts) + // disallow setting current admin as new admin + for acc.PubKey.Equals(newAdmin.PubKey) { + newAdmin, _ = simtypes.RandomAcc(r, accounts) + } + + msg := group.MsgUpdateGroupAdmin{ + GroupId: groupID, + Admin: account.GetAddress().String(), + NewAdmin: newAdmin.Address.String(), + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupAdmin, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// SimulateMsgUpdateGroupMetadata generates a MsgUpdateGroupMetadata with random values +func SimulateMsgUpdateGroupMetadata(ak group.AccountKeeper, bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + groupInfo, acc, account, err := randomGroup(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMetadata, ""), nil, err + } + if groupInfo == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMetadata, ""), nil, nil + } + groupID := groupInfo.GroupId + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMetadata, "fee error"), nil, err + } + + msg := group.MsgUpdateGroupMetadata{ + GroupId: groupID, + Admin: account.GetAddress().String(), + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMetadata, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// SimulateMsgUpdateGroupMembers generates a MsgUpdateGroupMembers with random values +func SimulateMsgUpdateGroupMembers(ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + groupInfo, acc, account, err := randomGroup(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMembers, ""), nil, err + } + if groupInfo == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMembers, ""), nil, nil + } + groupID := groupInfo.GroupId + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMembers, "fee error"), nil, err + } + + member, _ := simtypes.RandomAcc(r, accounts) + + members := []group.Member{ + { + Address: member.Address.String(), + Weight: fmt.Sprintf("%d", GroupMemberWeight), + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + }, + } + + msg := group.MsgUpdateGroupMembers{ + GroupId: groupID, + Admin: acc.Address.String(), + MemberUpdates: members, + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupMembers, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// SimulateMsgUpdateGroupPolicyAdmin generates a MsgUpdateGroupPolicyAdmin with random values +func SimulateMsgUpdateGroupPolicyAdmin(ak group.AccountKeeper, bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + _, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyAdmin, ""), nil, err + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyAdmin, "no group policy found"), nil, nil + } + groupPolicyAddr := groupPolicy.Address + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyAdmin, "fee error"), nil, err + } + + if len(accounts) == 1 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyAdmin, "can't set a new admin with only one account"), nil, nil + } + newAdmin, _ := simtypes.RandomAcc(r, accounts) + // disallow setting current admin as new admin + for acc.PubKey.Equals(newAdmin.PubKey) { + newAdmin, _ = simtypes.RandomAcc(r, accounts) + } + + msg := group.MsgUpdateGroupPolicyAdmin{ + Admin: acc.Address.String(), + Address: groupPolicyAddr, + NewAdmin: newAdmin.Address.String(), + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyAdmin, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// // SimulateMsgUpdateGroupPolicyDecisionPolicy generates a NewMsgUpdateGroupPolicyDecisionPolicyRequest with random values +func SimulateMsgUpdateGroupPolicyDecisionPolicy(ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + _, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, ""), nil, err + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, "no group policy found"), nil, nil + } + groupPolicyAddr := groupPolicy.Address + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, "fee error"), nil, err + } + + groupPolicyBech32, err := sdk.AccAddressFromBech32(groupPolicyAddr) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, fmt.Sprintf("fail to decide bech32 address: %s", err.Error())), nil, nil + } + + msg, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(acc.Address, groupPolicyBech32, &group.ThresholdDecisionPolicy{ + Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 20)), + Timeout: time.Second * time.Duration(simtypes.RandIntBetween(r, 100, 1000)), + }) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, err.Error()), nil, err + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + return simtypes.NewOperationMsg(msg, true, "", nil), nil, err + } +} + +// // SimulateMsgUpdateGroupPolicyMetadata generates a MsgUpdateGroupPolicyMetadata with random values +func SimulateMsgUpdateGroupPolicyMetadata(ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + _, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, ""), nil, err + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, "no group policy found"), nil, nil + } + groupPolicyAddr := groupPolicy.Address + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, "fee error"), nil, err + } + + msg := group.MsgUpdateGroupPolicyMetadata{ + Admin: acc.Address.String(), + Address: groupPolicyAddr, + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + } + + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// SimulateMsgVote generates a MsgVote with random values +func SimulateMsgVote(ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + g, groupPolicy, _, _, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, ""), nil, err + } + if g == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "no group found"), nil, nil + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "no group policy found"), nil, nil + } + groupPolicyAddr := groupPolicy.Address + + // Pick a random member from the group + ctx := sdk.WrapSDKContext(sdkCtx) + acc, account, err := randomMember(r, k, ak, ctx, accounts, g.GroupId) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, ""), nil, err + } + if account == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "no group member found"), nil, nil + } + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "fee error"), nil, err + } + + proposalsResult, err := k.ProposalsByGroupPolicy(ctx, &group.QueryProposalsByGroupPolicyRequest{Address: groupPolicyAddr}) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "fail to query group info"), nil, err + } + proposals := proposalsResult.GetProposals() + if len(proposals) == 0 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "no proposals found"), nil, nil + } + + var proposal *group.Proposal + proposalID := -1 + + for _, p := range proposals { + if p.Status == group.ProposalStatusSubmitted { + timeout := p.Timeout + proposal = p + proposalID = int(p.ProposalId) + if timeout.Before(sdkCtx.BlockTime()) || timeout.Equal(sdkCtx.BlockTime()) { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "voting period ended: skipping"), nil, nil + } + break + } + } + + // return no-op if no proposal found + if proposalID == -1 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "no proposals found"), nil, nil + } + + // Ensure that group and group policy haven't been modified since the proposal submission. + if proposal.GroupPolicyVersion != groupPolicy.Version { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "group policy has been modified"), nil, nil + } + if proposal.GroupVersion != g.Version { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "group has been modified"), nil, nil + } + + // Ensure member hasn't already voted + res, _ := k.VoteByProposalVoter(ctx, &group.QueryVoteByProposalVoterRequest{ + Voter: acc.Address.String(), + ProposalId: uint64(proposalID), + }) + if res != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgVote, "member has already voted"), nil, nil + } + + msg := group.MsgVote{ + ProposalId: uint64(proposalID), + Voter: acc.Address.String(), + Choice: group.Choice_CHOICE_YES, + Metadata: []byte(simtypes.RandStringOfLength(r, 10)), + } + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + + if err != nil { + if strings.Contains(err.Error(), "group was modified") || strings.Contains(err.Error(), "group account was modified") { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "no-op:group/group-account was modified"), nil, nil + } + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +// // SimulateMsgExec generates a MsgExec with random values +func SimulateMsgExec(ak group.AccountKeeper, + bk group.BankKeeper, k keeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + _, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, ""), nil, err + } + if groupPolicy == nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no group policy found"), nil, nil + } + groupPolicyAddr := groupPolicy.Address + + spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress()) + fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "fee error"), nil, err + } + + ctx := sdk.WrapSDKContext(sdkCtx) + proposalsResult, err := k.ProposalsByGroupPolicy(ctx, &group.QueryProposalsByGroupPolicyRequest{Address: groupPolicyAddr}) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "fail to query group info"), nil, err + } + proposals := proposalsResult.GetProposals() + if len(proposals) == 0 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no proposals found"), nil, nil + } + + proposalID := -1 + + for _, proposal := range proposals { + if proposal.Status == group.ProposalStatusClosed { + proposalID = int(proposal.ProposalId) + break + } + } + + // return no-op if no proposal found + if proposalID == -1 { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no proposals found"), nil, nil + } + + msg := group.MsgExec{ + ProposalId: uint64(proposalID), + Signer: acc.Address.String(), + } + txGen := simappparams.MakeTestEncodingConfig().TxConfig + tx, err := helpers.GenTx( + txGen, + []sdk.Msg{&msg}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + acc.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyMetadata, "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + if strings.Contains(err.Error(), "group was modified") || strings.Contains(err.Error(), "group account was modified") { + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "no-op:group/group-account was modified"), nil, nil + } + return simtypes.NoOpMsg(group.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + } +} + +func randomGroup(r *rand.Rand, k keeper.Keeper, ak group.AccountKeeper, + ctx sdk.Context, accounts []simtypes.Account) (groupInfo *group.GroupInfo, acc simtypes.Account, account authtypes.AccountI, err error) { + groupID := k.GetGroupSequence(ctx) + + switch { + case groupID > initialGroupID: + // select a random ID between [initialGroupID, groupID] + groupID = uint64(simtypes.RandIntBetween(r, int(initialGroupID), int(groupID))) + + default: + // This is called on the first call to this function + // in order to update the global variable + initialGroupID = groupID + } + + res, err := k.GroupInfo(sdk.WrapSDKContext(ctx), &group.QueryGroupInfoRequest{GroupId: groupID}) + if err != nil { + return nil, simtypes.Account{}, nil, err + } + + groupInfo = res.Info + groupAdmin := groupInfo.Admin + found := -1 + for i := range accounts { + if accounts[i].Address.String() == groupAdmin { + found = i + break + } + } + if found < 0 { + return nil, simtypes.Account{}, nil, nil + } + acc = accounts[found] + account = ak.GetAccount(ctx, acc.Address) + return groupInfo, acc, account, nil +} + +func randomGroupPolicy(r *rand.Rand, k keeper.Keeper, ak group.AccountKeeper, + ctx sdk.Context, accounts []simtypes.Account) (groupInfo *group.GroupInfo, groupPolicyInfo *group.GroupPolicyInfo, acc simtypes.Account, account authtypes.AccountI, err error) { + groupInfo, _, _, err = randomGroup(r, k, ak, ctx, accounts) + if err != nil { + return nil, nil, simtypes.Account{}, nil, err + } + if groupInfo == nil { + return nil, nil, simtypes.Account{}, nil, nil + } + groupID := groupInfo.GroupId + + result, err := k.GroupPoliciesByGroup(sdk.WrapSDKContext(ctx), &group.QueryGroupPoliciesByGroupRequest{GroupId: groupID}) + if err != nil { + return groupInfo, nil, simtypes.Account{}, nil, err + } + + n := randIntInRange(r, len(result.GroupPolicies)) + if n < 0 { + return groupInfo, nil, simtypes.Account{}, nil, nil + } + groupPolicyInfo = result.GroupPolicies[n] + + idx := findAccount(accounts, groupPolicyInfo.Admin) + if idx < 0 { + return groupInfo, nil, simtypes.Account{}, nil, nil + } + acc = accounts[idx] + account = ak.GetAccount(ctx, acc.Address) + return groupInfo, groupPolicyInfo, acc, account, nil +} + +func randomMember(r *rand.Rand, k keeper.Keeper, ak group.AccountKeeper, + ctx context.Context, accounts []simtypes.Account, groupID uint64) (acc simtypes.Account, account authtypes.AccountI, err error) { + res, err := k.GroupMembers(ctx, &group.QueryGroupMembersRequest{ + GroupId: groupID, + }) + if err != nil { + return simtypes.Account{}, nil, err + } + n := randIntInRange(r, len(res.Members)) + if n < 0 { + return simtypes.Account{}, nil, err + } + idx := findAccount(accounts, res.Members[n].Member.Address) + if idx < 0 { + return simtypes.Account{}, nil, err + } + acc = accounts[idx] + account = ak.GetAccount(sdk.UnwrapSDKContext(ctx), acc.Address) + return acc, account, nil +} + +func randIntInRange(r *rand.Rand, l int) int { + if l == 0 { + return -1 + } + if l == 1 { + return 0 + } else { + return simtypes.RandIntBetween(r, 0, l-1) + } +} + +func findAccount(accounts []simtypes.Account, addr string) (idx int) { + idx = -1 + for i := range accounts { + if accounts[i].Address.String() == addr { + idx = i + break + } + } + return idx +} diff --git a/x/group/simulation/operations_test.go b/x/group/simulation/operations_test.go new file mode 100644 index 0000000000..31e082434e --- /dev/null +++ b/x/group/simulation/operations_test.go @@ -0,0 +1,650 @@ +package simulation_test + +import ( + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/bank/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/cosmos-sdk/x/group/simulation" +) + +type SimTestSuite struct { + suite.Suite + + ctx sdk.Context + app *simapp.SimApp +} + +func (suite *SimTestSuite) SetupTest() { + checkTx := false + app := simapp.Setup(suite.T(), checkTx) + suite.app = app + suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{}) +} + +func (suite *SimTestSuite) TestWeightedOperations() { + cdc := suite.app.AppCodec() + appParams := make(simtypes.AppParams) + + weightedOps := simulation.WeightedOperations(appParams, cdc, suite.app.AccountKeeper, + suite.app.BankKeeper, suite.app.GroupKeeper, cdc, + ) + + s := rand.NewSource(1) + r := rand.New(s) + accs := suite.getTestingAccounts(r, 3) + + expected := []struct { + weight int + opMsgRoute string + opMsgName string + }{ + {simulation.WeightMsgCreateGroup, group.MsgCreateGroup{}.Route(), simulation.TypeMsgCreateGroup}, + {simulation.WeightMsgCreateGroupPolicy, group.MsgCreateGroupPolicy{}.Route(), simulation.TypeMsgCreateGroupPolicy}, + {simulation.WeightMsgCreateProposal, group.MsgCreateProposal{}.Route(), simulation.TypeMsgCreateProposal}, + {simulation.WeightMsgVote, group.MsgVote{}.Route(), simulation.TypeMsgVote}, + {simulation.WeightMsgExec, group.MsgExec{}.Route(), simulation.TypeMsgExec}, + {simulation.WeightMsgUpdateGroupMetadata, group.MsgUpdateGroupMetadata{}.Route(), simulation.TypeMsgUpdateGroupMetadata}, + {simulation.WeightMsgUpdateGroupAdmin, group.MsgUpdateGroupAdmin{}.Route(), simulation.TypeMsgUpdateGroupAdmin}, + {simulation.WeightMsgUpdateGroupMembers, group.MsgUpdateGroupMembers{}.Route(), simulation.TypeMsgUpdateGroupMembers}, + {simulation.WeightMsgUpdateGroupPolicyAdmin, group.MsgUpdateGroupPolicyAdmin{}.Route(), simulation.TypeMsgUpdateGroupPolicyAdmin}, + {simulation.WeightMsgUpdateGroupPolicyDecisionPolicy, group.MsgUpdateGroupPolicyDecisionPolicy{}.Route(), simulation.TypeMsgUpdateGroupPolicyDecisionPolicy}, + {simulation.WeightMsgUpdateGroupPolicyMetadata, group.MsgUpdateGroupPolicyMetadata{}.Route(), simulation.TypeMsgUpdateGroupPolicyMetadata}, + } + + for i, w := range weightedOps { + operationMsg, _, _ := w.Op()(r, suite.app.BaseApp, suite.ctx, accs, "") + // the following checks are very much dependent from the ordering of the output given + // by WeightedOperations. if the ordering in WeightedOperations changes some tests + // will fail + // fmt.Printf("%v %v\n", operationMsg, w.Weight()) + suite.Require().Equal(expected[i].weight, w.Weight(), "weight should be the same") + suite.Require().Equal(expected[i].opMsgRoute, operationMsg.Route, "route should be the same") + suite.Require().Equal(expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") + } +} + +func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account { + accounts := simtypes.RandomAccounts(r, n) + + initAmt := sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) + initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) + + // add coins to the accounts + for _, account := range accounts { + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, account.Address) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) + suite.Require().NoError(testutil.FundAccount(suite.app.BankKeeper, suite.ctx, account.Address, initCoins)) + } + + return accounts +} + +func (suite *SimTestSuite) TestSimulateCreateGroup() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 1) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + acc := accounts[0] + + // execute operation + op := simulation.SimulateMsgCreateGroup(suite.app.AccountKeeper, suite.app.BankKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgCreateGroup + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(acc.Address.String(), msg.Admin) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateCreateGroupPolicy() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 1) + acc := accounts[0] + + // setup a group + _, err := suite.app.GroupKeeper.CreateGroup(sdk.WrapSDKContext(suite.ctx), + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgCreateGroupPolicy(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgCreateGroupPolicy + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(acc.Address.String(), msg.Admin) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateCreateProposal() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 1) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: acc.Address.String(), + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgCreateProposal(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgCreateProposal + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(groupPolicyRes.Address, msg.Address) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateVote() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 1) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + addr := acc.Address.String() + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: addr, + Members: []group.Member{ + { + Address: addr, + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: addr, + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // setup a proposal + proposalReq, err := group.NewMsgCreateProposalRequest(groupPolicyRes.Address, []string{addr}, []sdk.Msg{ + &banktypes.MsgSend{ + FromAddress: groupPolicyRes.Address, + ToAddress: addr, + Amount: sdk.Coins{sdk.NewInt64Coin("token", 100)}, + }, + }, []byte{}, 0) + suite.Require().NoError(err) + _, err = suite.app.GroupKeeper.CreateProposal(ctx, proposalReq) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgVote(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgVote + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(addr, msg.Voter) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateExec() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 1) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + addr := acc.Address.String() + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: addr, + Members: []group.Member{ + { + Address: addr, + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: addr, + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // setup a proposal + proposalReq, err := group.NewMsgCreateProposalRequest(groupPolicyRes.Address, []string{addr}, []sdk.Msg{ + &banktypes.MsgSend{ + FromAddress: groupPolicyRes.Address, + ToAddress: addr, + Amount: sdk.Coins{sdk.NewInt64Coin("token", 100)}, + }, + }, []byte{}, 0) + suite.Require().NoError(err) + proposalRes, err := suite.app.GroupKeeper.CreateProposal(ctx, proposalReq) + suite.Require().NoError(err) + + // vote + _, err = suite.app.GroupKeeper.Vote(ctx, &group.MsgVote{ + ProposalId: proposalRes.ProposalId, + Voter: addr, + Choice: group.Choice_CHOICE_YES, + }) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgExec(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgExec + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(addr, msg.Signer) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupAdmin() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + _, err := suite.app.GroupKeeper.CreateGroup(sdk.WrapSDKContext(suite.ctx), + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupAdmin(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupAdmin + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(acc.Address.String(), msg.Admin) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupMetadata() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + _, err := suite.app.GroupKeeper.CreateGroup(sdk.WrapSDKContext(suite.ctx), + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupMetadata(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupMetadata + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(acc.Address.String(), msg.Admin) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupMembers() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + _, err := suite.app.GroupKeeper.CreateGroup(sdk.WrapSDKContext(suite.ctx), + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupMembers(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupMembers + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(acc.Address.String(), msg.Admin) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyAdmin() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: acc.Address.String(), + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupPolicyAdmin(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupPolicyAdmin + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(groupPolicyRes.Address, msg.Address) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyDecisionPolicy() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: acc.Address.String(), + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupPolicyDecisionPolicy(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupPolicyDecisionPolicy + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(groupPolicyRes.Address, msg.Address) + suite.Require().Len(futureOperations, 0) +} + +func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyMetadata() { + // setup 1 account + s := rand.NewSource(1) + r := rand.New(s) + accounts := suite.getTestingAccounts(r, 2) + acc := accounts[0] + + // setup a group + ctx := sdk.WrapSDKContext(suite.ctx) + groupRes, err := suite.app.GroupKeeper.CreateGroup(ctx, + &group.MsgCreateGroup{ + Admin: acc.Address.String(), + Members: []group.Member{ + { + Address: acc.Address.String(), + Weight: "1", + }, + }, + }, + ) + suite.Require().NoError(err) + + // setup a group account + accountReq := &group.MsgCreateGroupPolicy{ + Admin: acc.Address.String(), + GroupId: groupRes.GroupId, + Metadata: nil, + } + err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour)) + suite.Require().NoError(err) + groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq) + suite.Require().NoError(err) + + // begin a new block + suite.app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: suite.app.LastBlockHeight() + 1, + AppHash: suite.app.LastCommitID().Hash, + }, + }) + + // execute operation + op := simulation.SimulateMsgUpdateGroupPolicyMetadata(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.GroupKeeper) + operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") + suite.Require().NoError(err) + + var msg group.MsgUpdateGroupPolicyMetadata + err = group.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + suite.Require().NoError(err) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(groupPolicyRes.Address, msg.Address) + suite.Require().Len(futureOperations, 0) +} + +func TestSimTestSuite(t *testing.T) { + suite.Run(t, new(SimTestSuite)) +} diff --git a/x/group/spec/05_client.md b/x/group/spec/05_client.md index 0b8f024475..4b09fb6816 100644 --- a/x/group/spec/05_client.md +++ b/x/group/spec/05_client.md @@ -695,26 +695,26 @@ Example Output: } ``` -### GroupPolicysByGroup +### GroupPoliciesByGroup -The `GroupPolicysByGroup` endpoint allows users to query for group policies by group id with pagination flags. +The `GroupPoliciesByGroup` endpoint allows users to query for group policies by group id with pagination flags. ```bash -cosmos.group.v1beta1.Query/GroupPolicysByGroup +cosmos.group.v1beta1.Query/GroupPoliciesByGroup ``` Example: ```bash grpcurl -plaintext \ - -d '{"group_id":"1"}' localhost:9090 cosmos.group.v1beta1.Query/GroupPolicysByGroup + -d '{"group_id":"1"}' localhost:9090 cosmos.group.v1beta1.Query/GroupPoliciesByGroup ``` Example Output: ```bash { - "GroupPolicys": [ + "GroupPolicies": [ { "address": "cosmos1..", "groupId": "1", @@ -736,26 +736,26 @@ Example Output: } ``` -### GroupPolicysByAdmin +### GroupPoliciesByAdmin -The `GroupPolicysByAdmin` endpoint allows users to query for group policies by admin account address with pagination flags. +The `GroupPoliciesByAdmin` endpoint allows users to query for group policies by admin account address with pagination flags. ```bash -cosmos.group.v1beta1.Query/GroupPolicysByAdmin +cosmos.group.v1beta1.Query/GroupPoliciesByAdmin ``` Example: ```bash grpcurl -plaintext \ - -d '{"admin":"cosmos1.."}' localhost:9090 cosmos.group.v1beta1.Query/GroupPolicysByAdmin + -d '{"admin":"cosmos1.."}' localhost:9090 cosmos.group.v1beta1.Query/GroupPoliciesByAdmin ``` Example Output: ```bash { - "GroupPolicys": [ + "GroupPolicies": [ { "address": "cosmos1..", "groupId": "1", @@ -1114,9 +1114,9 @@ Example Output: } ``` -### GroupPolicysByGroup +### GroupPoliciesByGroup -The `GroupPolicysByGroup` endpoint allows users to query for group policies by group id with pagination flags. +The `GroupPoliciesByGroup` endpoint allows users to query for group policies by group id with pagination flags. ```bash /cosmos/group/v1beta1/group_policies_by_group/{group_id} @@ -1165,9 +1165,9 @@ Example Output: } ``` -### GroupPolicysByAdmin +### GroupPoliciesByAdmin -The `GroupPolicysByAdmin` endpoint allows users to query for group policies by admin account address with pagination flags. +The `GroupPoliciesByAdmin` endpoint allows users to query for group policies by admin account address with pagination flags. ```bash /cosmos/group/v1beta1/group_policies_by_admin/{admin} diff --git a/x/group/types.go b/x/group/types.go index 88fc9389bd..b5802ec52d 100644 --- a/x/group/types.go +++ b/x/group/types.go @@ -113,7 +113,7 @@ func (p *ThresholdDecisionPolicy) Validate(g GroupInfo) error { return sdkerrors.Wrap(err, "group total weight") } if threshold.Cmp(totalWeight) > 0 { - return sdkerrors.Wrap(errors.ErrInvalid, "policy threshold should not be greater than the total group weight") + return sdkerrors.Wrapf(errors.ErrInvalid, "policy threshold %s should not be greater than the total group weight %s", p.Threshold, g.TotalWeight) } return nil } @@ -256,7 +256,7 @@ func (p Proposal) ValidateBasic() error { } _, err := sdk.AccAddressFromBech32(p.Address) if err != nil { - return sdkerrors.Wrap(err, "proposer group policy address") + return sdkerrors.Wrap(err, "proposal group policy address") } if p.GroupVersion == 0 { return sdkerrors.Wrap(errors.ErrEmpty, "proposal group version")