feat: Add simulations to group module (#10723)

## Description

Closes: #9901



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [x] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
This commit is contained in:
Marie Gauthier 2022-01-21 11:52:26 +01:00 committed by GitHub
parent fd5b97bd7b
commit f52d87003c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 2215 additions and 192 deletions

View File

@ -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 (

View File

@ -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"`

1
go.sum
View File

@ -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=

View File

@ -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;

View File

@ -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
}

View File

@ -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},

View File

@ -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)

View File

@ -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)
}

View File

@ -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))
}

View File

@ -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); {

View File

@ -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,
)
}

View File

@ -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 {

View File

@ -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{}))
}
})
}

View File

@ -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))
}
}
}

View File

@ -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)
}
})
}
}

View File

@ -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)
}

View File

@ -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))
}

View File

@ -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
}

View File

@ -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))
}

View File

@ -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}

View File

@ -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")