feat: Add genesis import/export to group module (#10659)
## Description Add genesis import/export and its related tests to group module. Closes: #9900 --- ### 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... - [ ] 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 - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] 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) - [ ] 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` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] 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:
parent
d64253f98a
commit
9aef070625
|
@ -0,0 +1,38 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package cosmos.group.v1beta1;
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/group";
|
||||
|
||||
import "cosmos/group/v1beta1/types.proto";
|
||||
|
||||
// GenesisState defines the group module's genesis state.
|
||||
message GenesisState {
|
||||
|
||||
// group_seq is the group table orm.Sequence,
|
||||
// it is used to get the next group ID.
|
||||
uint64 group_seq = 1;
|
||||
|
||||
// groups is the list of groups info.
|
||||
repeated GroupInfo groups = 2;
|
||||
|
||||
// group_members is the list of groups members.
|
||||
repeated GroupMember group_members = 3;
|
||||
|
||||
// group_policy_account_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;
|
||||
|
||||
// group_policies is the list of group policies info.
|
||||
repeated GroupPolicyInfo group_policies = 5;
|
||||
|
||||
// proposal_seq is the proposal table orm.Sequence,
|
||||
// it is used to get the next proposal ID.
|
||||
uint64 proposal_seq = 6;
|
||||
|
||||
// proposals is the list of proposals.
|
||||
repeated Proposal proposals = 7;
|
||||
|
||||
// votes is the list of votes.
|
||||
repeated Vote votes = 8;
|
||||
}
|
|
@ -361,18 +361,16 @@ func NewSimApp(
|
|||
upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName,
|
||||
evidencetypes.ModuleName, stakingtypes.ModuleName,
|
||||
authtypes.ModuleName, banktypes.ModuleName, govtypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName,
|
||||
authz.ModuleName, feegrant.ModuleName, nft.ModuleName,
|
||||
authz.ModuleName, feegrant.ModuleName, nft.ModuleName, group.ModuleName,
|
||||
paramstypes.ModuleName, vestingtypes.ModuleName,
|
||||
group.ModuleName,
|
||||
)
|
||||
app.mm.SetOrderEndBlockers(
|
||||
crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName,
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName,
|
||||
slashingtypes.ModuleName, minttypes.ModuleName,
|
||||
genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
|
||||
feegrant.ModuleName, nft.ModuleName,
|
||||
feegrant.ModuleName, nft.ModuleName, group.ModuleName,
|
||||
paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName,
|
||||
group.ModuleName,
|
||||
)
|
||||
|
||||
// NOTE: The genutils module must occur after staking so that pools are
|
||||
|
@ -383,10 +381,9 @@ func NewSimApp(
|
|||
app.mm.SetOrderInitGenesis(
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
|
||||
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName,
|
||||
genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, group.ModuleName,
|
||||
feegrant.ModuleName, nft.ModuleName,
|
||||
genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
|
||||
feegrant.ModuleName, nft.ModuleName, group.ModuleName,
|
||||
paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName,
|
||||
group.ModuleName,
|
||||
)
|
||||
|
||||
// Uncomment if you want to set a custom migration order here.
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
group "github.com/cosmos/cosmos-sdk/x/group/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
|
@ -179,6 +180,7 @@ func TestRunMigrations(t *testing.T) {
|
|||
"distribution": distribution.AppModule{}.ConsensusVersion(),
|
||||
"slashing": slashing.AppModule{}.ConsensusVersion(),
|
||||
"gov": gov.AppModule{}.ConsensusVersion(),
|
||||
"group": group.AppModule{}.ConsensusVersion(),
|
||||
"params": params.AppModule{}.ConsensusVersion(),
|
||||
"upgrade": upgrade.AppModule{}.ConsensusVersion(),
|
||||
"vesting": vesting.AppModule{}.ConsensusVersion(),
|
||||
|
|
|
@ -390,7 +390,7 @@ func MsgUpdateGroupPolicyAdminCmd() *cobra.Command {
|
|||
// MsgUpdateGroupPolicyDecisionPolicyCmd creates a CLI command for Msg/UpdateGroupPolicyDecisionPolicy.
|
||||
func MsgUpdateGroupPolicyDecisionPolicyCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "update-group-account-policy [admin] [group-policy-account] [decision-policy]",
|
||||
Use: "update-group-policy-decision-policy [admin] [group-policy-account] [decision-policy]",
|
||||
Short: "Update a group policy's decision policy",
|
||||
Args: cobra.ExactArgs(3),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package group
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// NewGenesisState creates a new genesis state with default values.
|
||||
func NewGenesisState() *GenesisState {
|
||||
return &GenesisState{}
|
||||
}
|
||||
|
||||
func (s GenesisState) Validate() error {
|
||||
groups := make(map[uint64]GroupInfo)
|
||||
groupPolicies := make(map[string]GroupPolicyInfo)
|
||||
groupMembers := make(map[uint64]GroupMember)
|
||||
proposals := make(map[uint64]Proposal)
|
||||
|
||||
for _, g := range s.Groups {
|
||||
if err := g.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "Group validation failed")
|
||||
}
|
||||
groups[g.GroupId] = *g
|
||||
}
|
||||
|
||||
for _, g := range s.GroupPolicies {
|
||||
|
||||
// check that group with group policy's GroupId exists
|
||||
if _, exists := groups[g.GroupId]; !exists {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrNotFound, fmt.Sprintf("group with GroupId %d doesn't exist", g.GroupId))
|
||||
}
|
||||
|
||||
if err := g.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "GroupPolicy validation failed")
|
||||
}
|
||||
groupPolicies[g.Address] = *g
|
||||
}
|
||||
|
||||
for _, g := range s.GroupMembers {
|
||||
|
||||
// check that group with group member's GroupId exists
|
||||
if _, exists := groups[g.GroupId]; !exists {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrNotFound, fmt.Sprintf("group member with GroupId %d doesn't exist", g.GroupId))
|
||||
}
|
||||
|
||||
if err := g.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "GroupMember validation failed")
|
||||
}
|
||||
groupMembers[g.GroupId] = *g
|
||||
}
|
||||
|
||||
for _, p := range s.Proposals {
|
||||
|
||||
// check that group policy with proposal address exists
|
||||
if _, exists := groupPolicies[p.Address]; !exists {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrNotFound, fmt.Sprintf("group policy account with address %s doesn't correspond to proposal address", p.Address))
|
||||
}
|
||||
|
||||
if err := p.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "Proposal validation failed")
|
||||
}
|
||||
proposals[p.ProposalId] = *p
|
||||
}
|
||||
|
||||
for _, v := range s.Votes {
|
||||
|
||||
if err := v.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "Vote validation failed")
|
||||
}
|
||||
|
||||
// check that proposal exists
|
||||
if _, exists := proposals[v.ProposalId]; !exists {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrNotFound, fmt.Sprintf("proposal with ProposalId %d doesn't exist", v.ProposalId))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (s GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
for _, g := range s.GroupPolicies {
|
||||
err := g.UnpackInterfaces(unpacker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, p := range s.Proposals {
|
||||
err := p.UnpackInterfaces(unpacker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,705 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: cosmos/group/v1beta1/genesis.proto
|
||||
|
||||
package group
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState defines the group module's genesis state.
|
||||
type GenesisState struct {
|
||||
// group_seq is the group table orm.Sequence,
|
||||
// it is used to get the next group ID.
|
||||
GroupSeq uint64 `protobuf:"varint,1,opt,name=group_seq,json=groupSeq,proto3" json:"group_seq,omitempty"`
|
||||
// groups is the list of groups info.
|
||||
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,
|
||||
// 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"`
|
||||
// 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,
|
||||
// it is used to get the next proposal ID.
|
||||
ProposalSeq uint64 `protobuf:"varint,6,opt,name=proposal_seq,json=proposalSeq,proto3" json:"proposal_seq,omitempty"`
|
||||
// proposals is the list of proposals.
|
||||
Proposals []*Proposal `protobuf:"bytes,7,rep,name=proposals,proto3" json:"proposals,omitempty"`
|
||||
// votes is the list of votes.
|
||||
Votes []*Vote `protobuf:"bytes,8,rep,name=votes,proto3" json:"votes,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState) ProtoMessage() {}
|
||||
func (*GenesisState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7eedba45e0e08e2c, []int{0}
|
||||
}
|
||||
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
|
||||
|
||||
func (m *GenesisState) GetGroupSeq() uint64 {
|
||||
if m != nil {
|
||||
return m.GroupSeq
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetGroups() []*GroupInfo {
|
||||
if m != nil {
|
||||
return m.Groups
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetGroupMembers() []*GroupMember {
|
||||
if m != nil {
|
||||
return m.GroupMembers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetGroupPolicyAccountSeq() uint64 {
|
||||
if m != nil {
|
||||
return m.GroupPolicyAccountSeq
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetGroupPolicies() []*GroupPolicyInfo {
|
||||
if m != nil {
|
||||
return m.GroupPolicies
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetProposalSeq() uint64 {
|
||||
if m != nil {
|
||||
return m.ProposalSeq
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetProposals() []*Proposal {
|
||||
if m != nil {
|
||||
return m.Proposals
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetVotes() []*Vote {
|
||||
if m != nil {
|
||||
return m.Votes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "cosmos.group.v1beta1.GenesisState")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("cosmos/group/v1beta1/genesis.proto", fileDescriptor_7eedba45e0e08e2c)
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Votes) > 0 {
|
||||
for iNdEx := len(m.Votes) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Votes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x42
|
||||
}
|
||||
}
|
||||
if len(m.Proposals) > 0 {
|
||||
for iNdEx := len(m.Proposals) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Proposals[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x3a
|
||||
}
|
||||
}
|
||||
if m.ProposalSeq != 0 {
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(m.ProposalSeq))
|
||||
i--
|
||||
dAtA[i] = 0x30
|
||||
}
|
||||
if len(m.GroupPolicies) > 0 {
|
||||
for iNdEx := len(m.GroupPolicies) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.GroupPolicies[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
}
|
||||
if m.GroupPolicyAccountSeq != 0 {
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(m.GroupPolicyAccountSeq))
|
||||
i--
|
||||
dAtA[i] = 0x20
|
||||
}
|
||||
if len(m.GroupMembers) > 0 {
|
||||
for iNdEx := len(m.GroupMembers) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.GroupMembers[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
}
|
||||
if len(m.Groups) > 0 {
|
||||
for iNdEx := len(m.Groups) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Groups[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
}
|
||||
if m.GroupSeq != 0 {
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(m.GroupSeq))
|
||||
i--
|
||||
dAtA[i] = 0x8
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovGenesis(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *GenesisState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.GroupSeq != 0 {
|
||||
n += 1 + sovGenesis(uint64(m.GroupSeq))
|
||||
}
|
||||
if len(m.Groups) > 0 {
|
||||
for _, e := range m.Groups {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.GroupMembers) > 0 {
|
||||
for _, e := range m.GroupMembers {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.GroupPolicyAccountSeq != 0 {
|
||||
n += 1 + sovGenesis(uint64(m.GroupPolicyAccountSeq))
|
||||
}
|
||||
if len(m.GroupPolicies) > 0 {
|
||||
for _, e := range m.GroupPolicies {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.ProposalSeq != 0 {
|
||||
n += 1 + sovGenesis(uint64(m.ProposalSeq))
|
||||
}
|
||||
if len(m.Proposals) > 0 {
|
||||
for _, e := range m.Proposals {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.Votes) > 0 {
|
||||
for _, e := range m.Votes {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenesis(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozGenesis(x uint64) (n int) {
|
||||
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GroupSeq", wireType)
|
||||
}
|
||||
m.GroupSeq = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.GroupSeq |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Groups = append(m.Groups, &GroupInfo{})
|
||||
if err := m.Groups[len(m.Groups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GroupMembers", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.GroupMembers = append(m.GroupMembers, &GroupMember{})
|
||||
if err := m.GroupMembers[len(m.GroupMembers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GroupPolicyAccountSeq", wireType)
|
||||
}
|
||||
m.GroupPolicyAccountSeq = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.GroupPolicyAccountSeq |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GroupPolicies", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.GroupPolicies = append(m.GroupPolicies, &GroupPolicyInfo{})
|
||||
if err := m.GroupPolicies[len(m.GroupPolicies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ProposalSeq", wireType)
|
||||
}
|
||||
m.ProposalSeq = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ProposalSeq |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Proposals = append(m.Proposals, &Proposal{})
|
||||
if err := m.Proposals[len(m.Proposals)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Votes", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Votes = append(m.Votes, &Vote{})
|
||||
if err := m.Votes[len(m.Votes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenesis(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenesis
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
|
@ -0,0 +1,750 @@
|
|||
package group
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
memberPub = secp256k1.GenPrivKey().PubKey()
|
||||
accPub = secp256k1.GenPrivKey().PubKey()
|
||||
accAddr = sdk.AccAddress(accPub.Address())
|
||||
memberAddr = sdk.AccAddress(memberPub.Address())
|
||||
)
|
||||
|
||||
func TestGenesisStateValidate(t *testing.T) {
|
||||
|
||||
submittedAt := time.Now().UTC()
|
||||
timeout := submittedAt.Add(time.Second * 1).UTC()
|
||||
|
||||
groupPolicy := &GroupPolicyInfo{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
}
|
||||
err := groupPolicy.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
||||
Threshold: "1",
|
||||
Timeout: time.Second,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// create another group policy to set invalid decision policy for testing
|
||||
groupPolicy2 := &GroupPolicyInfo{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
}
|
||||
err = groupPolicy2.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
||||
Threshold: "1",
|
||||
Timeout: 0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
proposal := &Proposal{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: ProposalStatusClosed,
|
||||
Result: ProposalResultAccepted,
|
||||
VoteState: Tally{
|
||||
YesCount: "1",
|
||||
NoCount: "0",
|
||||
AbstainCount: "0",
|
||||
VetoCount: "0",
|
||||
},
|
||||
Timeout: timeout,
|
||||
ExecutorResult: ProposalExecutorResultSuccess,
|
||||
}
|
||||
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
||||
FromAddress: accAddr.String(),
|
||||
ToAddress: memberAddr.String(),
|
||||
Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)},
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
genesisState GenesisState
|
||||
expErr bool
|
||||
}{
|
||||
{
|
||||
"valid genesisState",
|
||||
GenesisState{
|
||||
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,
|
||||
GroupPolicies: []*GroupPolicyInfo{groupPolicy},
|
||||
ProposalSeq: 1,
|
||||
Proposals: []*Proposal{proposal},
|
||||
Votes: []*Vote{{ProposalId: proposal.ProposalId, Voter: memberAddr.String(), SubmittedAt: submittedAt, Choice: Choice_CHOICE_YES}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"empty genesisState",
|
||||
GenesisState{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"empty group id",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 0,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group admin",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: "invalid admin",
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group version",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 0,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group TotalWeight",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "-1",
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy address",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
{
|
||||
Address: "invalid address",
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy admin",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: "invalid admin",
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy's group id",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 0,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy version",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 0,
|
||||
Metadata: []byte("policy metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy's decision policy",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
DecisionPolicy: groupPolicy2.DecisionPolicy,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group member's group id",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupMembers: []*GroupMember{
|
||||
{
|
||||
GroupId: 0,
|
||||
Member: &Member{
|
||||
Address: memberAddr.String(),
|
||||
Weight: "1", Metadata: []byte("member metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group member address",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupMembers: []*GroupMember{
|
||||
{
|
||||
GroupId: 1,
|
||||
Member: &Member{
|
||||
Address: "invalid address",
|
||||
Weight: "1", Metadata: []byte("member metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group member weight",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupMembers: []*GroupMember{
|
||||
{
|
||||
GroupId: 1,
|
||||
Member: &Member{
|
||||
Address: memberAddr.String(),
|
||||
Weight: "-1", Metadata: []byte("member metadata"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid proposal id",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 0,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy address of proposal",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: "invalid address",
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group version of proposal",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 0,
|
||||
GroupPolicyVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid group policy version",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid VoteState with negative YesCount",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: ProposalStatusClosed,
|
||||
Result: ProposalResultAccepted,
|
||||
VoteState: Tally{
|
||||
YesCount: "-1",
|
||||
NoCount: "0",
|
||||
AbstainCount: "0",
|
||||
VetoCount: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid VoteState with negative NoCount",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: ProposalStatusClosed,
|
||||
Result: ProposalResultAccepted,
|
||||
VoteState: Tally{
|
||||
YesCount: "0",
|
||||
NoCount: "-1",
|
||||
AbstainCount: "0",
|
||||
VetoCount: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid VoteState with negative AbstainCount",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: ProposalStatusClosed,
|
||||
Result: ProposalResultAccepted,
|
||||
VoteState: Tally{
|
||||
YesCount: "0",
|
||||
NoCount: "0",
|
||||
AbstainCount: "-1",
|
||||
VetoCount: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid VoteState with negative VetoCount",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: ProposalStatusClosed,
|
||||
Result: ProposalResultAccepted,
|
||||
VoteState: Tally{
|
||||
YesCount: "0",
|
||||
NoCount: "0",
|
||||
AbstainCount: "0",
|
||||
VetoCount: "-1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid voter",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
proposal,
|
||||
},
|
||||
Votes: []*Vote{
|
||||
{
|
||||
ProposalId: proposal.ProposalId,
|
||||
Voter: "invalid voter",
|
||||
SubmittedAt: submittedAt,
|
||||
Choice: Choice_CHOICE_YES,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid proposal id",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
proposal,
|
||||
},
|
||||
Votes: []*Vote{
|
||||
{
|
||||
ProposalId: 0,
|
||||
Voter: memberAddr.String(),
|
||||
SubmittedAt: submittedAt,
|
||||
Choice: Choice_CHOICE_YES,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"vote on proposal that doesn't exist",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
proposal,
|
||||
},
|
||||
Votes: []*Vote{
|
||||
{
|
||||
ProposalId: 2,
|
||||
Voter: memberAddr.String(),
|
||||
SubmittedAt: submittedAt,
|
||||
Choice: Choice_CHOICE_YES,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid choice",
|
||||
GenesisState{
|
||||
Groups: []*GroupInfo{
|
||||
{
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Metadata: []byte("1"),
|
||||
Version: 1,
|
||||
TotalWeight: "1",
|
||||
},
|
||||
},
|
||||
GroupPolicies: []*GroupPolicyInfo{
|
||||
groupPolicy,
|
||||
},
|
||||
Proposals: []*Proposal{
|
||||
proposal,
|
||||
},
|
||||
Votes: []*Vote{
|
||||
{
|
||||
ProposalId: proposal.ProposalId,
|
||||
Voter: memberAddr.String(),
|
||||
SubmittedAt: submittedAt,
|
||||
Choice: Choice_CHOICE_UNSPECIFIED,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
err := tc.genesisState.Validate()
|
||||
if tc.expErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/group"
|
||||
)
|
||||
|
||||
func (k Keeper) InitGenesis(ctx types.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState group.GenesisState
|
||||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
|
||||
if err := k.groupTable.Import(ctx.KVStore(k.key), genesisState.Groups, genesisState.GroupSeq); err != nil {
|
||||
panic(errors.Wrap(err, "groups"))
|
||||
}
|
||||
|
||||
if err := k.groupMemberTable.Import(ctx.KVStore(k.key), genesisState.GroupMembers, 0); err != nil {
|
||||
panic(errors.Wrap(err, "group members"))
|
||||
}
|
||||
|
||||
if err := k.groupPolicyTable.Import(ctx.KVStore(k.key), genesisState.GroupPolicies, 0); err != nil {
|
||||
panic(errors.Wrap(err, "group policies"))
|
||||
}
|
||||
|
||||
if err := k.groupPolicySeq.InitVal(ctx.KVStore(k.key), genesisState.GroupPolicyAccountSeq); err != nil {
|
||||
panic(errors.Wrap(err, "group policy account seq"))
|
||||
}
|
||||
|
||||
if err := k.proposalTable.Import(ctx.KVStore(k.key), genesisState.Proposals, genesisState.ProposalSeq); err != nil {
|
||||
panic(errors.Wrap(err, "proposals"))
|
||||
}
|
||||
|
||||
if err := k.voteTable.Import(ctx.KVStore(k.key), genesisState.Votes, 0); err != nil {
|
||||
panic(errors.Wrap(err, "votes"))
|
||||
}
|
||||
|
||||
return []abci.ValidatorUpdate{}
|
||||
|
||||
}
|
||||
|
||||
func (k Keeper) ExportGenesis(ctx types.Context, cdc codec.JSONCodec) *group.GenesisState {
|
||||
genesisState := group.NewGenesisState()
|
||||
|
||||
var groups []*group.GroupInfo
|
||||
|
||||
groupSeq, err := k.groupTable.Export(ctx.KVStore(k.key), &groups)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "groups"))
|
||||
}
|
||||
genesisState.Groups = groups
|
||||
genesisState.GroupSeq = groupSeq
|
||||
|
||||
var groupMembers []*group.GroupMember
|
||||
_, err = k.groupMemberTable.Export(ctx.KVStore(k.key), &groupMembers)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "group members"))
|
||||
}
|
||||
genesisState.GroupMembers = groupMembers
|
||||
|
||||
var groupPolicies []*group.GroupPolicyInfo
|
||||
_, err = k.groupPolicyTable.Export(ctx.KVStore(k.key), &groupPolicies)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "group policies"))
|
||||
}
|
||||
genesisState.GroupPolicies = groupPolicies
|
||||
genesisState.GroupPolicyAccountSeq = k.groupPolicySeq.CurVal(ctx.KVStore(k.key))
|
||||
|
||||
var proposals []*group.Proposal
|
||||
proposalSeq, err := k.proposalTable.Export(ctx.KVStore(k.key), &proposals)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "proposals"))
|
||||
}
|
||||
genesisState.Proposals = proposals
|
||||
genesisState.ProposalSeq = proposalSeq
|
||||
|
||||
var votes []*group.Vote
|
||||
_, err = k.voteTable.Export(ctx.KVStore(k.key), &votes)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "votes"))
|
||||
}
|
||||
genesisState.Votes = votes
|
||||
|
||||
return genesisState
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package keeper_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/group"
|
||||
"github.com/cosmos/cosmos-sdk/x/group/keeper"
|
||||
)
|
||||
|
||||
type GenesisTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
app *simapp.SimApp
|
||||
ctx context.Context
|
||||
sdkCtx sdk.Context
|
||||
keeper keeper.Keeper
|
||||
cdc *codec.ProtoCodec
|
||||
}
|
||||
|
||||
func TestGenesisTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(GenesisTestSuite))
|
||||
}
|
||||
|
||||
var (
|
||||
memberPub = secp256k1.GenPrivKey().PubKey()
|
||||
accPub = secp256k1.GenPrivKey().PubKey()
|
||||
accAddr = sdk.AccAddress(accPub.Address())
|
||||
memberAddr = sdk.AccAddress(memberPub.Address())
|
||||
)
|
||||
|
||||
func (s *GenesisTestSuite) SetupSuite() {
|
||||
checkTx := false
|
||||
db := dbm.NewMemDB()
|
||||
encCdc := simapp.MakeTestEncodingConfig()
|
||||
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{})
|
||||
|
||||
s.app = app
|
||||
s.sdkCtx = app.BaseApp.NewUncachedContext(checkTx, tmproto.Header{})
|
||||
s.keeper = app.GroupKeeper
|
||||
s.cdc = codec.NewProtoCodec(app.InterfaceRegistry())
|
||||
s.ctx = sdk.WrapSDKContext(s.sdkCtx)
|
||||
}
|
||||
|
||||
func (s *GenesisTestSuite) TestInitExportGenesis() {
|
||||
sdkCtx := s.sdkCtx
|
||||
ctx := s.ctx
|
||||
cdc := s.cdc
|
||||
|
||||
submittedAt := time.Now().UTC()
|
||||
timeout := submittedAt.Add(time.Second * 1).UTC()
|
||||
|
||||
groupPolicy := &group.GroupPolicyInfo{
|
||||
Address: accAddr.String(),
|
||||
GroupId: 1,
|
||||
Admin: accAddr.String(),
|
||||
Version: 1,
|
||||
Metadata: []byte("policy metadata"),
|
||||
}
|
||||
err := groupPolicy.SetDecisionPolicy(&group.ThresholdDecisionPolicy{
|
||||
Threshold: "1",
|
||||
Timeout: time.Second,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
proposal := &group.Proposal{
|
||||
ProposalId: 1,
|
||||
Address: accAddr.String(),
|
||||
Metadata: []byte("proposal metadata"),
|
||||
GroupVersion: 1,
|
||||
GroupPolicyVersion: 1,
|
||||
Proposers: []string{
|
||||
memberAddr.String(),
|
||||
},
|
||||
SubmittedAt: submittedAt,
|
||||
Status: group.ProposalStatusClosed,
|
||||
Result: group.ProposalResultAccepted,
|
||||
VoteState: group.Tally{
|
||||
YesCount: "1",
|
||||
NoCount: "0",
|
||||
AbstainCount: "0",
|
||||
VetoCount: "0",
|
||||
},
|
||||
Timeout: timeout,
|
||||
ExecutorResult: group.ProposalExecutorResultSuccess,
|
||||
}
|
||||
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
||||
FromAddress: accAddr.String(),
|
||||
ToAddress: memberAddr.String(),
|
||||
Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)},
|
||||
}})
|
||||
s.Require().NoError(err)
|
||||
|
||||
genesisState := &group.GenesisState{
|
||||
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,
|
||||
GroupPolicies: []*group.GroupPolicyInfo{groupPolicy},
|
||||
ProposalSeq: 1,
|
||||
Proposals: []*group.Proposal{proposal},
|
||||
Votes: []*group.Vote{{ProposalId: proposal.ProposalId, Voter: memberAddr.String(), SubmittedAt: submittedAt, Choice: group.Choice_CHOICE_YES}},
|
||||
}
|
||||
genesisBytes, err := cdc.MarshalJSON(genesisState)
|
||||
s.Require().NoError(err)
|
||||
|
||||
genesisData := map[string]json.RawMessage{
|
||||
group.ModuleName: genesisBytes,
|
||||
}
|
||||
|
||||
s.keeper.InitGenesis(sdkCtx, cdc, genesisData[group.ModuleName])
|
||||
|
||||
for i, g := range genesisState.Groups {
|
||||
res, err := s.keeper.GroupInfo(ctx, &group.QueryGroupInfoRequest{
|
||||
GroupId: g.GroupId,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(g, res.Info)
|
||||
|
||||
membersRes, err := s.keeper.GroupMembers(ctx, &group.QueryGroupMembersRequest{
|
||||
GroupId: g.GroupId,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(len(membersRes.Members), 1)
|
||||
s.Require().Equal(membersRes.Members[0], genesisState.GroupMembers[i])
|
||||
}
|
||||
|
||||
for _, g := range genesisState.GroupPolicies {
|
||||
res, err := s.keeper.GroupPolicyInfo(ctx, &group.QueryGroupPolicyInfoRequest{
|
||||
Address: g.Address,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.assertGroupPoliciesEqual(g, res.Info)
|
||||
}
|
||||
|
||||
for _, g := range genesisState.Proposals {
|
||||
res, err := s.keeper.Proposal(ctx, &group.QueryProposalRequest{
|
||||
ProposalId: g.ProposalId,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.assertProposalsEqual(g, res.Proposal)
|
||||
|
||||
votesRes, err := s.keeper.VotesByProposal(ctx, &group.QueryVotesByProposalRequest{
|
||||
ProposalId: g.ProposalId,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(len(votesRes.Votes), 1)
|
||||
s.Require().Equal(votesRes.Votes[0], genesisState.Votes[0])
|
||||
}
|
||||
|
||||
exported := s.keeper.ExportGenesis(sdkCtx, cdc)
|
||||
bz, err := cdc.MarshalJSON(exported)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var exportedGenesisState group.GenesisState
|
||||
err = cdc.UnmarshalJSON(bz, &exportedGenesisState)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(genesisState.Groups, exportedGenesisState.Groups)
|
||||
s.Require().Equal(genesisState.GroupMembers, exportedGenesisState.GroupMembers)
|
||||
|
||||
s.Require().Equal(len(genesisState.GroupPolicies), len(exportedGenesisState.GroupPolicies))
|
||||
for i, g := range genesisState.GroupPolicies {
|
||||
res := exportedGenesisState.GroupPolicies[i]
|
||||
s.Require().NoError(err)
|
||||
s.assertGroupPoliciesEqual(g, res)
|
||||
}
|
||||
|
||||
s.Require().Equal(len(genesisState.Proposals), len(exportedGenesisState.Proposals))
|
||||
for i, g := range genesisState.Proposals {
|
||||
res := exportedGenesisState.Proposals[i]
|
||||
s.Require().NoError(err)
|
||||
s.assertProposalsEqual(g, res)
|
||||
}
|
||||
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.ProposalSeq, exportedGenesisState.ProposalSeq)
|
||||
|
||||
}
|
||||
|
||||
func (s *GenesisTestSuite) assertGroupPoliciesEqual(g *group.GroupPolicyInfo, other *group.GroupPolicyInfo) {
|
||||
require := s.Require()
|
||||
require.Equal(g.Address, other.Address)
|
||||
require.Equal(g.GroupId, other.GroupId)
|
||||
require.Equal(g.Admin, other.Admin)
|
||||
require.Equal(g.Metadata, other.Metadata)
|
||||
require.Equal(g.Version, other.Version)
|
||||
require.Equal(g.GetDecisionPolicy(), other.GetDecisionPolicy())
|
||||
}
|
||||
|
||||
func (s *GenesisTestSuite) assertProposalsEqual(g *group.Proposal, other *group.Proposal) {
|
||||
require := s.Require()
|
||||
require.Equal(g.ProposalId, other.ProposalId)
|
||||
require.Equal(g.Address, other.Address)
|
||||
require.Equal(g.Metadata, other.Metadata)
|
||||
require.Equal(g.Proposers, other.Proposers)
|
||||
require.Equal(g.SubmittedAt, other.SubmittedAt)
|
||||
require.Equal(g.GroupVersion, other.GroupVersion)
|
||||
require.Equal(g.GroupPolicyVersion, other.GroupPolicyVersion)
|
||||
require.Equal(g.Status, other.Status)
|
||||
require.Equal(g.Result, other.Result)
|
||||
require.Equal(g.VoteState, other.VoteState)
|
||||
require.Equal(g.Timeout, other.Timeout)
|
||||
require.Equal(g.ExecutorResult, other.ExecutorResult)
|
||||
require.Equal(g.GetMsgs(), other.GetMsgs())
|
||||
}
|
|
@ -106,14 +106,14 @@ func (q Keeper) GroupPoliciesByGroup(goCtx context.Context, request *group.Query
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var accounts []*group.GroupPolicyInfo
|
||||
pageRes, err := orm.Paginate(it, request.Pagination, &accounts)
|
||||
var policies []*group.GroupPolicyInfo
|
||||
pageRes, err := orm.Paginate(it, request.Pagination, &policies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &group.QueryGroupPoliciesByGroupResponse{
|
||||
GroupPolicies: accounts,
|
||||
GroupPolicies: policies,
|
||||
Pagination: pageRes,
|
||||
}, nil
|
||||
}
|
||||
|
@ -133,14 +133,14 @@ func (q Keeper) GroupPoliciesByAdmin(goCtx context.Context, request *group.Query
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var accounts []*group.GroupPolicyInfo
|
||||
pageRes, err := orm.Paginate(it, request.Pagination, &accounts)
|
||||
var policies []*group.GroupPolicyInfo
|
||||
pageRes, err := orm.Paginate(it, request.Pagination, &policies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &group.QueryGroupPoliciesByAdminResponse{
|
||||
GroupPolicies: accounts,
|
||||
GroupPolicies: policies,
|
||||
Pagination: pageRes,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package module
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
@ -58,14 +59,16 @@ func (AppModuleBasic) Name() string {
|
|||
// DefaultGenesis returns default genesis state as raw bytes for the group
|
||||
// module.
|
||||
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
|
||||
// TODO: return default genesis state
|
||||
return nil
|
||||
return cdc.MustMarshalJSON(group.NewGenesisState())
|
||||
}
|
||||
|
||||
// ValidateGenesis performs genesis state validation for the group module.
|
||||
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
|
||||
// TODO: perform genesis validation
|
||||
return nil
|
||||
var data group.GenesisState
|
||||
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", group.ModuleName, err)
|
||||
}
|
||||
return data.Validate()
|
||||
}
|
||||
|
||||
// GetQueryCmd returns the cli query commands for the group module
|
||||
|
@ -127,15 +130,15 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
|
|||
// InitGenesis performs genesis initialization for the group module. It returns
|
||||
// no validator updates.
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
// TODO: initialize genesis for group module
|
||||
am.keeper.InitGenesis(ctx, cdc, data)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
// ExportGenesis returns the exported genesis state as raw bytes for the group
|
||||
// module.
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
||||
// TODO: export genesis for group module
|
||||
return nil
|
||||
gs := am.keeper.ExportGenesis(ctx, cdc)
|
||||
return cdc.MustMarshalJSON(gs)
|
||||
}
|
||||
|
||||
// RegisterServices registers a gRPC query service to respond to the
|
||||
|
|
|
@ -63,8 +63,7 @@ func (m MsgCreateGroup) ValidateBasic() error {
|
|||
}
|
||||
for i := range m.Members {
|
||||
member := m.Members[i]
|
||||
if _, err := math.NewDecFromString(member.Weight); err != nil {
|
||||
// if _, err := math.ParsePositiveDecimal(member.Weight); err != nil {
|
||||
if _, err := math.NewPositiveDecFromString(member.Weight); err != nil {
|
||||
return sdkerrors.Wrap(err, "member weight")
|
||||
}
|
||||
}
|
||||
|
@ -76,8 +75,7 @@ func (m Member) ValidateBasic() error {
|
|||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "address")
|
||||
}
|
||||
if _, err := math.NewDecFromString(m.Weight); err != nil {
|
||||
// if _, err := math.ParseNonNegativeDecimal(m.Weight); err != nil {
|
||||
if _, err := math.NewNonNegativeDecFromString(m.Weight); err != nil {
|
||||
return sdkerrors.Wrap(err, "weight")
|
||||
}
|
||||
|
||||
|
|
|
@ -495,18 +495,18 @@ Example:
|
|||
simd tx group update-group-policy-metadata cosmos1.. cosmos1.. "AQ=="
|
||||
```
|
||||
|
||||
#### update-group-account-policy
|
||||
#### update-group-policy-decision-policy
|
||||
|
||||
The `update-group-account-policy` command allows users to update a group policy's decision policy.
|
||||
The `update-group-policy-decision-policy` command allows users to update a group policy's decision policy.
|
||||
|
||||
```bash
|
||||
simd tx group update-group-account-policy [admin] [group-policy-account] [decision-policy] [flags]
|
||||
simd tx group update-group-policy-decision-policy [admin] [group-policy-account] [decision-policy] [flags]
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
simd tx group update-group-account-policy cosmos1.. cosmos1.. '{"@type":"/cosmos.group.v1beta1.ThresholdDecisionPolicy", "threshold":"2", "timeout":"1000s"}'
|
||||
simd tx group update-group-policy-decision-policy cosmos1.. cosmos1.. '{"@type":"/cosmos.group.v1beta1.ThresholdDecisionPolicy", "threshold":"2", "timeout":"1000s"}'
|
||||
```
|
||||
|
||||
#### create-proposal
|
||||
|
|
|
@ -17,7 +17,7 @@ This module allows the creation and management of on-chain multisig accounts and
|
|||
|
||||
1. **[Concepts](01_concepts.md)**
|
||||
- [Group](01_concepts.md#group)
|
||||
- [Group Account](01_concepts.md#group-account)
|
||||
- [Group Policy](01_concepts.md#group-policy)
|
||||
- [Decision Policy](01_concepts.md#decision-policy)
|
||||
- [Proposal](01_concepts.md#proposal)
|
||||
- [Voting](01_concepts.md#voting)
|
||||
|
@ -25,7 +25,7 @@ This module allows the creation and management of on-chain multisig accounts and
|
|||
2. **[State](02_state.md)**
|
||||
- [Group Table](02_state.md#group-table)
|
||||
- [Group Member Table](02_state.md#group-member-table)
|
||||
- [Group Account Table](02_state.md#group-account-table)
|
||||
- [Group Policy Table](02_state.md#group-policy-table)
|
||||
- [Proposal](02_state.md#proposal-table)
|
||||
- [Vote Table](02_state.md#vote-table)
|
||||
3. **[Msg Service](03_messages.md)**
|
||||
|
@ -33,18 +33,18 @@ This module allows the creation and management of on-chain multisig accounts and
|
|||
- [Msg/UpdateGroupMembers](03_messages.md#msgupdategroupmembers)
|
||||
- [Msg/UpdateGroupAdmin](03_messages.md#msgupdategroupadmin)
|
||||
- [Msg/UpdateGroupMetadata](03_messages.md#msgupdategroupmetadata)
|
||||
- [Msg/CreateGroupAccount](03_messages.md#msgcreategroupaccount)
|
||||
- [Msg/UpdateGroupAccountAdmin](03_messages.md#msgupdategroupaccountadmin)
|
||||
- [Msg/UpdateGroupAccountDecisionPolicy](03_messages.md#msgupdategroupaccountdecisionpolicy)
|
||||
- [Msg/UpdateGroupAccountMetadata](03_messages.md#msgupdategroupaccountmetadata)
|
||||
- [Msg/CreateGroupPolicy](03_messages.md#msgcreategrouppolicy)
|
||||
- [Msg/UpdateGroupPolicyAdmin](03_messages.md#msgupdategrouppolicyadmin)
|
||||
- [Msg/UpdateGroupPolicyDecisionPolicy](03_messages.md#msgupdategrouppolicydecisionpolicy)
|
||||
- [Msg/UpdateGroupPolicyMetadata](03_messages.md#msgupdategrouppolicymetadata)
|
||||
- [Msg/CreateProposal](03_messages.md#msgcreateproposal)
|
||||
- [Msg/Vote](03_messages.md#msgvote)
|
||||
- [Msg/Exec](03_messages.md#msgexec)
|
||||
4. **[Events](04_events.md)**
|
||||
- [EventCreateGroup](04_events.md#eventcreategroup)
|
||||
- [EventUpdateGroup](04_events.md#eventupdategroup)
|
||||
- [EventCreateGroupAccount](04_events.md#eventcreategroupaccount)
|
||||
- [EventUpdateGroupAccount](04_events.md#eventupdategroupaccount)
|
||||
- [EventCreateGroupPolicy](04_events.md#eventcreategrouppolicy)
|
||||
- [EventUpdateGroupPolicy](04_events.md#eventupdategrouppolicy)
|
||||
- [EventCreateProposal](04_events.md#eventcreateproposal)
|
||||
- [EventVote](04_events.md#eventvote)
|
||||
- [EventExec](04_events.md#eventexec)
|
||||
|
|
|
@ -167,6 +167,29 @@ func (g GroupPolicyInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error
|
|||
return unpacker.UnpackAny(g.DecisionPolicy, &decisionPolicy)
|
||||
}
|
||||
|
||||
func (g GroupInfo) PrimaryKeyFields() []interface{} {
|
||||
return []interface{}{g.GroupId}
|
||||
}
|
||||
|
||||
func (g GroupInfo) ValidateBasic() error {
|
||||
if g.GroupId == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group's GroupId")
|
||||
}
|
||||
|
||||
_, err := sdk.AccAddressFromBech32(g.Admin)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "admin")
|
||||
}
|
||||
|
||||
if _, err := math.NewNonNegativeDecFromString(g.TotalWeight); err != nil {
|
||||
return sdkerrors.Wrap(err, "total weight")
|
||||
}
|
||||
if g.Version == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "version")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g GroupPolicyInfo) PrimaryKeyFields() []interface{} {
|
||||
addr, err := sdk.AccAddressFromBech32(g.Address)
|
||||
if err != nil {
|
||||
|
@ -175,32 +198,34 @@ func (g GroupPolicyInfo) PrimaryKeyFields() []interface{} {
|
|||
return []interface{}{addr.Bytes()}
|
||||
}
|
||||
|
||||
func (g Proposal) PrimaryKeyFields() []interface{} {
|
||||
return []interface{}{g.ProposalId}
|
||||
}
|
||||
|
||||
func (g GroupPolicyInfo) ValidateBasic() error {
|
||||
_, err := sdk.AccAddressFromBech32(g.Admin)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "admin")
|
||||
return sdkerrors.Wrap(err, "group policy admin")
|
||||
}
|
||||
|
||||
_, err = sdk.AccAddressFromBech32(g.Address)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "group policy")
|
||||
return sdkerrors.Wrap(err, "group policy account address")
|
||||
}
|
||||
|
||||
if g.GroupId == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group")
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group policy's group id")
|
||||
}
|
||||
if g.Version == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "version")
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group policy version")
|
||||
}
|
||||
policy := g.GetDecisionPolicy()
|
||||
|
||||
if policy == nil {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "policy")
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group policy's decision policy")
|
||||
}
|
||||
if err := policy.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "policy")
|
||||
return sdkerrors.Wrap(err, "group policy's decision policy")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -214,12 +239,46 @@ func (g GroupMember) PrimaryKeyFields() []interface{} {
|
|||
|
||||
func (g GroupMember) ValidateBasic() error {
|
||||
if g.GroupId == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group")
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "group member's group id")
|
||||
}
|
||||
|
||||
err := g.Member.ValidateBasic()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "member")
|
||||
return sdkerrors.Wrap(err, "group member")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Proposal) ValidateBasic() error {
|
||||
|
||||
if p.ProposalId == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "proposal id")
|
||||
}
|
||||
_, err := sdk.AccAddressFromBech32(p.Address)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "proposer group policy address")
|
||||
}
|
||||
if p.GroupVersion == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "proposal group version")
|
||||
}
|
||||
if p.GroupPolicyVersion == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "proposal group policy version")
|
||||
}
|
||||
_, err = p.VoteState.GetYesCount()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "proposal VoteState yes count")
|
||||
}
|
||||
_, err = p.VoteState.GetNoCount()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "proposal VoteState no count")
|
||||
}
|
||||
_, err = p.VoteState.GetAbstainCount()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "proposal VoteState abstain count")
|
||||
}
|
||||
_, err = p.VoteState.GetVetoCount()
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "proposal VoteState veto count")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -232,6 +291,26 @@ func (v Vote) PrimaryKeyFields() []interface{} {
|
|||
return []interface{}{v.ProposalId, addr.Bytes()}
|
||||
}
|
||||
|
||||
var _ orm.Validateable = Vote{}
|
||||
|
||||
func (v Vote) ValidateBasic() error {
|
||||
|
||||
_, err := sdk.AccAddressFromBech32(v.Voter)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "voter")
|
||||
}
|
||||
if v.ProposalId == 0 {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "voter ProposalId")
|
||||
}
|
||||
if v.Choice == Choice_CHOICE_UNSPECIFIED {
|
||||
return sdkerrors.Wrap(errors.ErrEmpty, "voter choice")
|
||||
}
|
||||
if _, ok := Choice_name[int32(v.Choice)]; !ok {
|
||||
return sdkerrors.Wrap(errors.ErrInvalid, "choice")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (q QueryGroupPoliciesByGroupResponse) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
return unpackGroupPolicies(unpacker, q.GroupPolicies)
|
||||
|
|
Loading…
Reference in New Issue