From bab877d5fe886404653f597017bf2120ff0aa97a Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 2 Mar 2022 17:59:52 +0530 Subject: [PATCH 01/17] wip: tally --- x/group/abci.go | 23 +++++++++++++++++++++++ x/group/keeper/keeper.go | 9 +++++++++ 2 files changed, 32 insertions(+) create mode 100644 x/group/abci.go diff --git a/x/group/abci.go b/x/group/abci.go new file mode 100644 index 000000000000..314c86f73f43 --- /dev/null +++ b/x/group/abci.go @@ -0,0 +1,23 @@ +package group + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/regen-network/regen-ledger/x/group" +) + +func EndBlocker(ctx sdk.Context, k keeper.Keeper) { + storeKey := sdk.NewKVStoreKey(StoreKey) + timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) + it, _ := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(storeKey), sdk.PrefixEndBytes(timeBytes)) + + var proposal group.Proposal + for { + _, err = it.LoadNext(&proposal) + if errors.ErrORMIteratorDone.Is(err) { + break + } + } +} diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 96f05a53ee12..12241cf1d1e9 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -35,6 +35,7 @@ const ( ProposalTableSeqPrefix byte = 0x31 ProposalByGroupPolicyIndexPrefix byte = 0x32 ProposalByProposerIndexPrefix byte = 0x33 + ProposalsByVotingPeriodEndPrefix byte = 0x34 // Vote Table VoteTablePrefix byte = 0x40 @@ -66,6 +67,7 @@ type Keeper struct { proposalTable orm.AutoUInt64Table proposalByGroupPolicyIndex orm.Index proposalByProposerIndex orm.Index + ProposalsByVotingPeriodEnd orm.Index // Vote Table voteTable orm.PrimaryKeyTable @@ -181,6 +183,13 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddle if err != nil { panic(err.Error()) } + k.ProposalsByVotingPeriodEnd, err = orm.NewIndex(proposalTable, ProposalsByVotingPeriodEndPrefix, func(value interface{}) ([]interface{}, error) { + votingPeriodEnd := value.(*group.Proposal).VotingPeriodEnd + return []interface{}{sdk.FormatTimeBytes(votingPeriodEnd)}, nil + }, []byte{}) + if err != nil { + panic(err.Error()) + } k.proposalTable = *proposalTable // Vote Table From 02729c22716eb6c75a83190097720a7205ca5872 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 2 Mar 2022 20:33:07 +0530 Subject: [PATCH 02/17] draft --- x/group/abci.go | 23 ------------------ x/group/keeper/grpc_query.go | 45 ++++++++++++++++++++++++++++++++++++ x/group/module/abci.go | 10 ++++++++ 3 files changed, 55 insertions(+), 23 deletions(-) delete mode 100644 x/group/abci.go create mode 100644 x/group/module/abci.go diff --git a/x/group/abci.go b/x/group/abci.go deleted file mode 100644 index 314c86f73f43..000000000000 --- a/x/group/abci.go +++ /dev/null @@ -1,23 +0,0 @@ -package group - -import ( - "errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/group/keeper" - "github.com/regen-network/regen-ledger/x/group" -) - -func EndBlocker(ctx sdk.Context, k keeper.Keeper) { - storeKey := sdk.NewKVStoreKey(StoreKey) - timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) - it, _ := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(storeKey), sdk.PrefixEndBytes(timeBytes)) - - var proposal group.Proposal - for { - _, err = it.LoadNext(&proposal) - if errors.ErrORMIteratorDone.Is(err) { - break - } - } -} diff --git a/x/group/keeper/grpc_query.go b/x/group/keeper/grpc_query.go index c9151813b886..1567180947e7 100644 --- a/x/group/keeper/grpc_query.go +++ b/x/group/keeper/grpc_query.go @@ -356,3 +356,48 @@ func (q Keeper) Tally(ctx sdk.Context, p group.Proposal, groupId uint64) (group. return tallyResult, nil } + +func (q Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { + timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) + it, _ := q.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(q.key), sdk.PrefixEndBytes(timeBytes)) + + var proposal group.Proposal + for { + _, err := it.LoadNext(&proposal) + if errors.ErrORMIteratorDone.Is(err) { + break + } + if err != nil { + return err + } + + // check whether the proposal can be tallied. + if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED { + continue + } + + var policyInfo group.GroupPolicyInfo + if policyInfo, err = q.getGroupPolicyInfo(ctx, proposal.Address); err != nil { + return err + } + + tallyRes, err := q.Tally(ctx, proposal, policyInfo.GroupId) + if err != nil { + return err + } + + proposal.FinalTallyResult = tallyRes + storeUpdates := func() error { + if err := q.proposalTable.Update(ctx.KVStore(q.key), proposal.Id, &proposal); err != nil { + return err + } + return nil + } + + if err := storeUpdates(); err != nil { + return err + } + } + + return nil +} diff --git a/x/group/module/abci.go b/x/group/module/abci.go new file mode 100644 index 000000000000..e5dac8f387c1 --- /dev/null +++ b/x/group/module/abci.go @@ -0,0 +1,10 @@ +package module + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/group/keeper" +) + +func EndBlocker(ctx sdk.Context, k keeper.Keeper) { + k.UpdateTallyOfVPEndProposals(ctx) +} From bba0b5def33ca1803ceca5ca5baf35070ba2e1a9 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 11:52:46 +0530 Subject: [PATCH 03/17] review suggestion --- x/group/keeper/grpc_query.go | 6 +++--- x/group/keeper/keeper.go | 36 ++++++++++++++++++++++++++++++++++++ x/group/keeper/msg_server.go | 10 +++++----- x/group/module/abci.go | 25 ++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/x/group/keeper/grpc_query.go b/x/group/keeper/grpc_query.go index 1567180947e7..7a453057dfbb 100644 --- a/x/group/keeper/grpc_query.go +++ b/x/group/keeper/grpc_query.go @@ -35,7 +35,7 @@ func (q Keeper) getGroupInfo(ctx sdk.Context, id uint64) (group.GroupInfo, error func (q Keeper) GroupPolicyInfo(goCtx context.Context, request *group.QueryGroupPolicyInfoRequest) (*group.QueryGroupPolicyInfoResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - groupPolicyInfo, err := q.getGroupPolicyInfo(ctx, request.Address) + groupPolicyInfo, err := q.GetGroupPolicyInfo(ctx, request.Address) if err != nil { return nil, err } @@ -43,7 +43,7 @@ func (q Keeper) GroupPolicyInfo(goCtx context.Context, request *group.QueryGroup return &group.QueryGroupPolicyInfoResponse{Info: &groupPolicyInfo}, nil } -func (q Keeper) getGroupPolicyInfo(ctx sdk.Context, accountAddress string) (group.GroupPolicyInfo, error) { +func (q Keeper) GetGroupPolicyInfo(ctx sdk.Context, accountAddress string) (group.GroupPolicyInfo, error) { var obj group.GroupPolicyInfo return obj, q.groupPolicyTable.GetOne(ctx.KVStore(q.key), orm.PrimaryKey(&group.GroupPolicyInfo{Address: accountAddress}), &obj) } @@ -377,7 +377,7 @@ func (q Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { } var policyInfo group.GroupPolicyInfo - if policyInfo, err = q.getGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = q.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { return err } diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 12241cf1d1e9..e9bbc3f853ce 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -10,6 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authmiddleware "github.com/cosmos/cosmos-sdk/x/auth/middleware" "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/cosmos-sdk/x/group/errors" "github.com/cosmos/cosmos-sdk/x/group/internal/orm" ) @@ -239,3 +240,38 @@ func (k Keeper) MaxMetadataLength() uint64 { return k.config.MaxMetadataLen } func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) } + +func (k Keeper) UpdateProposal(ctx sdk.Context, proposal group.Proposal) error { + if err := k.proposalTable.Update(ctx.KVStore(k.key), proposal.Id, &proposal); err != nil { + return err + } + + return nil +} + +func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func(proposal group.Proposal) (stop bool)) error { + it, _ := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) + var proposal group.Proposal + defer it.Close() + + for { + _, err := it.LoadNext(&proposal) + if errors.ErrORMIteratorDone.Is(err) { + break + } + if err != nil { + return err + } + + // check whether the proposal status is submitted. + if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED { + continue + } + + if cb(proposal) { + break + } + } + + return nil +} diff --git a/x/group/keeper/msg_server.go b/x/group/keeper/msg_server.go index 5cfa45eee18d..eb3a737553d7 100644 --- a/x/group/keeper/msg_server.go +++ b/x/group/keeper/msg_server.go @@ -439,7 +439,7 @@ func (k Keeper) SubmitProposal(goCtx context.Context, req *group.MsgSubmitPropos return nil, err } - policyAcc, err := k.getGroupPolicyInfo(ctx, req.Address) + policyAcc, err := k.GetGroupPolicyInfo(ctx, req.Address) if err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -547,7 +547,7 @@ func (k Keeper) WithdrawProposal(goCtx context.Context, req *group.MsgWithdrawPr } var policyInfo group.GroupPolicyInfo - if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -618,7 +618,7 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR var policyInfo group.GroupPolicyInfo // Ensure that group policy hasn't been modified since the proposal submission. - if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } if proposal.GroupPolicyVersion != policyInfo.Version { @@ -722,7 +722,7 @@ func (k Keeper) Exec(goCtx context.Context, req *group.MsgExec) (*group.MsgExecR } var policyInfo group.GroupPolicyInfo - if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -804,7 +804,7 @@ type groupPolicyActionFn func(m *group.GroupPolicyInfo) error // doUpdateGroupPolicy first makes sure that the group policy admin initiated the group policy update, // before performing the group policy update and emitting an event. func (k Keeper) doUpdateGroupPolicy(ctx sdk.Context, groupPolicy string, admin string, action groupPolicyActionFn, note string) error { - groupPolicyInfo, err := k.getGroupPolicyInfo(ctx, groupPolicy) + groupPolicyInfo, err := k.GetGroupPolicyInfo(ctx, groupPolicy) if err != nil { return sdkerrors.Wrap(err, "load group policy") } diff --git a/x/group/module/abci.go b/x/group/module/abci.go index e5dac8f387c1..076e7ba81b6f 100644 --- a/x/group/module/abci.go +++ b/x/group/module/abci.go @@ -2,9 +2,32 @@ package module import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/group" "github.com/cosmos/cosmos-sdk/x/group/keeper" ) func EndBlocker(ctx sdk.Context, k keeper.Keeper) { - k.UpdateTallyOfVPEndProposals(ctx) + updateTallyOfVPEndProposals(ctx, k) +} + +func updateTallyOfVPEndProposals(ctx sdk.Context, k keeper.Keeper) error { + k.IterateVPEndProposals(ctx, sdk.FormatTimeBytes(ctx.BlockTime()), func(proposal group.Proposal) (stop bool) { + + policyInfo, err := k.GetGroupPolicyInfo(ctx, proposal.Address) + if err != nil { + return true + } + + tallyRes, err := k.Tally(ctx, proposal, policyInfo.GroupId) + if err != nil { + return true + } + + proposal.FinalTallyResult = tallyRes + err = k.UpdateProposal(ctx, proposal) + + return err != nil + }) + + return nil } From 28e814b83f199064644174d6eff4b46e30bd6867 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 18:00:53 +0530 Subject: [PATCH 04/17] add tests --- x/group/keeper/keeper.go | 7 +- x/group/keeper/keeper_test.go | 119 ++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index e9bbc3f853ce..1828eb636877 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -250,10 +250,13 @@ func (k Keeper) UpdateProposal(ctx sdk.Context, proposal group.Proposal) error { } func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func(proposal group.Proposal) (stop bool)) error { - it, _ := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) - var proposal group.Proposal + it, err := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) + if err != nil { + return err + } defer it.Close() + var proposal group.Proposal for { _, err := it.LoadNext(&proposal) if errors.ErrORMIteratorDone.Is(err) { diff --git a/x/group/keeper/keeper_test.go b/x/group/keeper/keeper_test.go index c1349271a5f0..d7fb638c24c9 100644 --- a/x/group/keeper/keeper_test.go +++ b/x/group/keeper/keeper_test.go @@ -19,6 +19,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/group" "github.com/cosmos/cosmos-sdk/x/group/keeper" + "github.com/cosmos/cosmos-sdk/x/group/module" ) type TestSuite struct { @@ -30,6 +31,7 @@ type TestSuite struct { addrs []sdk.AccAddress groupID uint64 groupPolicyAddr sdk.AccAddress + policy group.DecisionPolicy keeper keeper.Keeper blockTime time.Time } @@ -71,6 +73,7 @@ func (s *TestSuite) SetupTest() { s.Require().NoError(err) policyRes, err := s.keeper.CreateGroupPolicy(s.ctx, policyReq) s.Require().NoError(err) + s.policy = policy addr, err := sdk.AccAddressFromBech32(policyRes.Address) s.Require().NoError(err) s.groupPolicyAddr = addr @@ -2355,6 +2358,122 @@ func (s *TestSuite) TestExecProposal() { } } +func (s *TestSuite) TestVPEndProposals() { + addrs := s.addrs + addr2 := addrs[1] + groupPolicy := s.groupPolicyAddr + + votingPeriod := s.policy.GetVotingPeriod() + ctx := s.sdkCtx + now := time.Now() + + msgSend := &banktypes.MsgSend{ + FromAddress: s.groupPolicyAddr.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + } + + proposers := []string{addr2.String()} + + specs := map[string]struct { + preRun func(sdkCtx sdk.Context) uint64 + proposalId uint64 + admin string + expErrMsg string + newCtx sdk.Context + tallyRes group.TallyResult + }{ + "tally updated after voting power end": { + preRun: func(sdkCtx sdk.Context) uint64 { + return submitProposal(s.ctx, s, []sdk.Msg{msgSend}, proposers) + }, + admin: proposers[0], + newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), + tallyRes: group.DefaultTallyResult(), + }, + "tally within voting period": { + preRun: func(sdkCtx sdk.Context) uint64 { + return submitProposal(s.ctx, s, []sdk.Msg{msgSend}, proposers) + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + }, + "tally within voting period(with votes)": { + preRun: func(sdkCtx sdk.Context) uint64 { + return submitProposalAndVote(s.ctx, s, []sdk.Msg{msgSend}, proposers, group.VOTE_OPTION_YES) + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + }, + "tally after voting period(with votes)": { + preRun: func(sdkCtx sdk.Context) uint64 { + return submitProposalAndVote(s.ctx, s, []sdk.Msg{msgSend}, proposers, group.VOTE_OPTION_YES) + }, + admin: proposers[0], + newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), + tallyRes: group.TallyResult{ + YesCount: "2", + NoCount: "0", + NoWithVetoCount: "0", + AbstainCount: "0", + }, + }, + "tally of closed proposal": { + preRun: func(sdkCtx sdk.Context) uint64 { + pId := submitProposal(s.ctx, s, []sdk.Msg{msgSend}, proposers) + _, err := s.keeper.WithdrawProposal(s.ctx, &group.MsgWithdrawProposal{ + ProposalId: pId, + Address: groupPolicy.String(), + }) + + s.Require().NoError(err) + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + }, + "tally of closed proposal (with votes)": { + preRun: func(sdkCtx sdk.Context) uint64 { + pId := submitProposalAndVote(s.ctx, s, []sdk.Msg{msgSend}, proposers, group.VOTE_OPTION_YES) + _, err := s.keeper.WithdrawProposal(s.ctx, &group.MsgWithdrawProposal{ + ProposalId: pId, + Address: groupPolicy.String(), + }) + + s.Require().NoError(err) + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + }, + } + + for msg, spec := range specs { + spec := spec + s.Run(msg, func() { + pId := spec.preRun(s.sdkCtx) + + module.EndBlocker(spec.newCtx, s.keeper) + resp, err := s.keeper.Proposal(spec.newCtx, &group.QueryProposalRequest{ + ProposalId: pId, + }) + + if spec.expErrMsg != "" { + s.Require().Error(err) + s.Require().Contains(err.Error(), spec.expErrMsg) + return + } + + s.Require().NoError(err) + s.Require().Equal(resp.GetProposal().FinalTallyResult, spec.tallyRes) + }) + } +} + func submitProposal( ctx context.Context, s *TestSuite, msgs []sdk.Msg, proposers []string) uint64 { From 3f61659b02a03639205d6c424422b7a05a982137 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 18:06:38 +0530 Subject: [PATCH 05/17] update tests --- x/group/keeper/grpc_query.go | 45 ------------------------------------ x/group/keeper/keeper.go | 37 ++++++++++++++++++++++------- x/group/module/abci.go | 25 +------------------- 3 files changed, 30 insertions(+), 77 deletions(-) diff --git a/x/group/keeper/grpc_query.go b/x/group/keeper/grpc_query.go index 7a453057dfbb..b80d49453dd7 100644 --- a/x/group/keeper/grpc_query.go +++ b/x/group/keeper/grpc_query.go @@ -356,48 +356,3 @@ func (q Keeper) Tally(ctx sdk.Context, p group.Proposal, groupId uint64) (group. return tallyResult, nil } - -func (q Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { - timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) - it, _ := q.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(q.key), sdk.PrefixEndBytes(timeBytes)) - - var proposal group.Proposal - for { - _, err := it.LoadNext(&proposal) - if errors.ErrORMIteratorDone.Is(err) { - break - } - if err != nil { - return err - } - - // check whether the proposal can be tallied. - if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED { - continue - } - - var policyInfo group.GroupPolicyInfo - if policyInfo, err = q.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { - return err - } - - tallyRes, err := q.Tally(ctx, proposal, policyInfo.GroupId) - if err != nil { - return err - } - - proposal.FinalTallyResult = tallyRes - storeUpdates := func() error { - if err := q.proposalTable.Update(ctx.KVStore(q.key), proposal.Id, &proposal); err != nil { - return err - } - return nil - } - - if err := storeUpdates(); err != nil { - return err - } - } - - return nil -} diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 1828eb636877..36826ecc26bf 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -241,14 +241,6 @@ func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) } -func (k Keeper) UpdateProposal(ctx sdk.Context, proposal group.Proposal) error { - if err := k.proposalTable.Update(ctx.KVStore(k.key), proposal.Id, &proposal); err != nil { - return err - } - - return nil -} - func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func(proposal group.Proposal) (stop bool)) error { it, err := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) if err != nil { @@ -278,3 +270,32 @@ func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func return nil } + +func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { + k.IterateVPEndProposals(ctx, sdk.FormatTimeBytes(ctx.BlockTime()), func(proposal group.Proposal) (stop bool) { + + policyInfo, err := k.GetGroupPolicyInfo(ctx, proposal.Address) + if err != nil { + return true + } + + tallyRes, err := k.Tally(ctx, proposal, policyInfo.GroupId) + if err != nil { + return true + } + + storeUpdates := func() error { + if err := k.proposalTable.Update(ctx.KVStore(k.key), proposal.Id, &proposal); err != nil { + return err + } + return nil + } + + proposal.FinalTallyResult = tallyRes + err = storeUpdates() + + return err != nil + }) + + return nil +} diff --git a/x/group/module/abci.go b/x/group/module/abci.go index 076e7ba81b6f..e5dac8f387c1 100644 --- a/x/group/module/abci.go +++ b/x/group/module/abci.go @@ -2,32 +2,9 @@ package module import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/group" "github.com/cosmos/cosmos-sdk/x/group/keeper" ) func EndBlocker(ctx sdk.Context, k keeper.Keeper) { - updateTallyOfVPEndProposals(ctx, k) -} - -func updateTallyOfVPEndProposals(ctx sdk.Context, k keeper.Keeper) error { - k.IterateVPEndProposals(ctx, sdk.FormatTimeBytes(ctx.BlockTime()), func(proposal group.Proposal) (stop bool) { - - policyInfo, err := k.GetGroupPolicyInfo(ctx, proposal.Address) - if err != nil { - return true - } - - tallyRes, err := k.Tally(ctx, proposal, policyInfo.GroupId) - if err != nil { - return true - } - - proposal.FinalTallyResult = tallyRes - err = k.UpdateProposal(ctx, proposal) - - return err != nil - }) - - return nil + k.UpdateTallyOfVPEndProposals(ctx) } From 631dbd52c39aaf79ead52bd4a1f0c167abb6bd7c Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 18:37:51 +0530 Subject: [PATCH 06/17] changes --- x/group/keeper/keeper.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 36826ecc26bf..f25d0632e834 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -241,8 +241,10 @@ func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) } -func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func(proposal group.Proposal) (stop bool)) error { +func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Proposal) (stop bool)) error { + timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) it, err := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) + if err != nil { return err } @@ -272,7 +274,7 @@ func (k Keeper) IterateVPEndProposals(ctx sdk.Context, timeBytes []byte, cb func } func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { - k.IterateVPEndProposals(ctx, sdk.FormatTimeBytes(ctx.BlockTime()), func(proposal group.Proposal) (stop bool) { + k.IterateVPEndProposals(ctx, func(proposal group.Proposal) (stop bool) { policyInfo, err := k.GetGroupPolicyInfo(ctx, proposal.Address) if err != nil { From 41b7ef28a63992c30bdde493181ddc3cae0853f7 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 18:44:51 +0530 Subject: [PATCH 07/17] changes --- x/group/keeper/keeper.go | 5 ----- x/group/module/module.go | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index f25d0632e834..7aff0b112ef7 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -260,11 +260,6 @@ func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Pr return err } - // check whether the proposal status is submitted. - if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED { - continue - } - if cb(proposal) { break } diff --git a/x/group/module/module.go b/x/group/module/module.go index 78102cfe9f52..6832dc1392a9 100644 --- a/x/group/module/module.go +++ b/x/group/module/module.go @@ -156,6 +156,7 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} // EndBlock does nothing func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + EndBlocker(ctx, am.keeper) return []abci.ValidatorUpdate{} } From 4b48870a77d988bd265c9c771916a1e1b6fc6c94 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 3 Mar 2022 18:46:31 +0530 Subject: [PATCH 08/17] revert `GetGroupPolicyInfo` --- x/group/keeper/grpc_query.go | 4 ++-- x/group/keeper/keeper.go | 2 +- x/group/keeper/msg_server.go | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x/group/keeper/grpc_query.go b/x/group/keeper/grpc_query.go index b80d49453dd7..c9151813b886 100644 --- a/x/group/keeper/grpc_query.go +++ b/x/group/keeper/grpc_query.go @@ -35,7 +35,7 @@ func (q Keeper) getGroupInfo(ctx sdk.Context, id uint64) (group.GroupInfo, error func (q Keeper) GroupPolicyInfo(goCtx context.Context, request *group.QueryGroupPolicyInfoRequest) (*group.QueryGroupPolicyInfoResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - groupPolicyInfo, err := q.GetGroupPolicyInfo(ctx, request.Address) + groupPolicyInfo, err := q.getGroupPolicyInfo(ctx, request.Address) if err != nil { return nil, err } @@ -43,7 +43,7 @@ func (q Keeper) GroupPolicyInfo(goCtx context.Context, request *group.QueryGroup return &group.QueryGroupPolicyInfoResponse{Info: &groupPolicyInfo}, nil } -func (q Keeper) GetGroupPolicyInfo(ctx sdk.Context, accountAddress string) (group.GroupPolicyInfo, error) { +func (q Keeper) getGroupPolicyInfo(ctx sdk.Context, accountAddress string) (group.GroupPolicyInfo, error) { var obj group.GroupPolicyInfo return obj, q.groupPolicyTable.GetOne(ctx.KVStore(q.key), orm.PrimaryKey(&group.GroupPolicyInfo{Address: accountAddress}), &obj) } diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 7aff0b112ef7..5a4c76e0d99e 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -271,7 +271,7 @@ func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Pr func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { k.IterateVPEndProposals(ctx, func(proposal group.Proposal) (stop bool) { - policyInfo, err := k.GetGroupPolicyInfo(ctx, proposal.Address) + policyInfo, err := k.getGroupPolicyInfo(ctx, proposal.Address) if err != nil { return true } diff --git a/x/group/keeper/msg_server.go b/x/group/keeper/msg_server.go index eb3a737553d7..5cfa45eee18d 100644 --- a/x/group/keeper/msg_server.go +++ b/x/group/keeper/msg_server.go @@ -439,7 +439,7 @@ func (k Keeper) SubmitProposal(goCtx context.Context, req *group.MsgSubmitPropos return nil, err } - policyAcc, err := k.GetGroupPolicyInfo(ctx, req.Address) + policyAcc, err := k.getGroupPolicyInfo(ctx, req.Address) if err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -547,7 +547,7 @@ func (k Keeper) WithdrawProposal(goCtx context.Context, req *group.MsgWithdrawPr } var policyInfo group.GroupPolicyInfo - if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -618,7 +618,7 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR var policyInfo group.GroupPolicyInfo // Ensure that group policy hasn't been modified since the proposal submission. - if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } if proposal.GroupPolicyVersion != policyInfo.Version { @@ -722,7 +722,7 @@ func (k Keeper) Exec(goCtx context.Context, req *group.MsgExec) (*group.MsgExecR } var policyInfo group.GroupPolicyInfo - if policyInfo, err = k.GetGroupPolicyInfo(ctx, proposal.Address); err != nil { + if policyInfo, err = k.getGroupPolicyInfo(ctx, proposal.Address); err != nil { return nil, sdkerrors.Wrap(err, "load group policy") } @@ -804,7 +804,7 @@ type groupPolicyActionFn func(m *group.GroupPolicyInfo) error // doUpdateGroupPolicy first makes sure that the group policy admin initiated the group policy update, // before performing the group policy update and emitting an event. func (k Keeper) doUpdateGroupPolicy(ctx sdk.Context, groupPolicy string, admin string, action groupPolicyActionFn, note string) error { - groupPolicyInfo, err := k.GetGroupPolicyInfo(ctx, groupPolicy) + groupPolicyInfo, err := k.getGroupPolicyInfo(ctx, groupPolicy) if err != nil { return sdkerrors.Wrap(err, "load group policy") } From 2fe00c8b3c07dc0b868913a1773fa93b22f62d23 Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 5 Mar 2022 12:13:44 +0530 Subject: [PATCH 09/17] fix tests --- x/group/keeper/keeper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 5a4c76e0d99e..d07af415be95 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -243,7 +243,7 @@ func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Proposal) (stop bool)) error { timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) - it, err := k.ProposalsByVotingPeriodEnd.Get(ctx.KVStore(k.key), sdk.PrefixEndBytes(timeBytes)) + it, err := k.ProposalsByVotingPeriodEnd.PrefixScan(ctx.KVStore(k.key), nil, timeBytes) if err != nil { return err From d468d602dd53b098e1e2e9443d81c33fb5156e8e Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 5 Mar 2022 12:17:13 +0530 Subject: [PATCH 10/17] review changes --- x/group/keeper/keeper_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/group/keeper/keeper_test.go b/x/group/keeper/keeper_test.go index d7fb638c24c9..8da6a4dec1e0 100644 --- a/x/group/keeper/keeper_test.go +++ b/x/group/keeper/keeper_test.go @@ -2385,7 +2385,7 @@ func (s *TestSuite) TestVPEndProposals() { }{ "tally updated after voting power end": { preRun: func(sdkCtx sdk.Context) uint64 { - return submitProposal(s.ctx, s, []sdk.Msg{msgSend}, proposers) + return submitProposal(sdkCtx, s, []sdk.Msg{msgSend}, proposers) }, admin: proposers[0], newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), From 2de4bd8664b387375fc765f00684022fa5d24f62 Mon Sep 17 00:00:00 2001 From: atheesh Date: Mon, 7 Mar 2022 16:18:08 +0530 Subject: [PATCH 11/17] fix tests --- x/group/keeper/keeper.go | 14 +++++---- x/group/keeper/keeper_test.go | 58 ++++++++++++++++++++++------------- x/group/module/abci.go | 4 ++- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index d07af415be95..ab542d1d784a 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -241,7 +241,7 @@ func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) } -func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Proposal) (stop bool)) error { +func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group.Proposal) (stop bool)) error { timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) it, err := k.ProposalsByVotingPeriodEnd.PrefixScan(ctx.KVStore(k.key), nil, timeBytes) @@ -269,14 +269,19 @@ func (k Keeper) IterateVPEndProposals(ctx sdk.Context, cb func(proposal group.Pr } func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { - k.IterateVPEndProposals(ctx, func(proposal group.Proposal) (stop bool) { + k.iterateProposalsByVPEnd(ctx, func(proposal group.Proposal) (stop bool) { policyInfo, err := k.getGroupPolicyInfo(ctx, proposal.Address) if err != nil { return true } - tallyRes, err := k.Tally(ctx, proposal, policyInfo.GroupId) + electorate, err := k.getGroupInfo(ctx, policyInfo.GroupId) + if err != nil { + return true + } + + err = k.doTallyAndUpdate(ctx, &proposal, electorate, policyInfo) if err != nil { return true } @@ -287,10 +292,7 @@ func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { } return nil } - - proposal.FinalTallyResult = tallyRes err = storeUpdates() - return err != nil }) diff --git a/x/group/keeper/keeper_test.go b/x/group/keeper/keeper_test.go index 70774a771e71..e620daf6ee42 100644 --- a/x/group/keeper/keeper_test.go +++ b/x/group/keeper/keeper_test.go @@ -2454,36 +2454,44 @@ func (s *TestSuite) TestVPEndProposals() { proposers := []string{addr2.String()} specs := map[string]struct { - preRun func(sdkCtx sdk.Context) uint64 - proposalId uint64 - admin string - expErrMsg string - newCtx sdk.Context - tallyRes group.TallyResult + preRun func(sdkCtx sdk.Context) uint64 + proposalId uint64 + admin string + expErrMsg string + newCtx sdk.Context + tallyRes group.TallyResult + expStatus group.ProposalStatus + expExecutorResult group.ProposalResult }{ "tally updated after voting power end": { preRun: func(sdkCtx sdk.Context) uint64 { return submitProposal(sdkCtx, s, []sdk.Msg{msgSend}, proposers) }, - admin: proposers[0], - newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), - tallyRes: group.DefaultTallyResult(), + admin: proposers[0], + newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, }, "tally within voting period": { preRun: func(sdkCtx sdk.Context) uint64 { return submitProposal(s.ctx, s, []sdk.Msg{msgSend}, proposers) }, - admin: proposers[0], - newCtx: ctx, - tallyRes: group.DefaultTallyResult(), + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, }, "tally within voting period(with votes)": { preRun: func(sdkCtx sdk.Context) uint64 { return submitProposalAndVote(s.ctx, s, []sdk.Msg{msgSend}, proposers, group.VOTE_OPTION_YES) }, - admin: proposers[0], - newCtx: ctx, - tallyRes: group.DefaultTallyResult(), + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, }, "tally after voting period(with votes)": { preRun: func(sdkCtx sdk.Context) uint64 { @@ -2497,6 +2505,8 @@ func (s *TestSuite) TestVPEndProposals() { NoWithVetoCount: "0", AbstainCount: "0", }, + expStatus: group.PROPOSAL_STATUS_CLOSED, + expExecutorResult: group.PROPOSAL_RESULT_ACCEPTED, }, "tally of closed proposal": { preRun: func(sdkCtx sdk.Context) uint64 { @@ -2509,9 +2519,11 @@ func (s *TestSuite) TestVPEndProposals() { s.Require().NoError(err) return pId }, - admin: proposers[0], - newCtx: ctx, - tallyRes: group.DefaultTallyResult(), + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_WITHDRAWN, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, }, "tally of closed proposal (with votes)": { preRun: func(sdkCtx sdk.Context) uint64 { @@ -2524,9 +2536,11 @@ func (s *TestSuite) TestVPEndProposals() { s.Require().NoError(err) return pId }, - admin: proposers[0], - newCtx: ctx, - tallyRes: group.DefaultTallyResult(), + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_WITHDRAWN, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, }, } @@ -2548,6 +2562,8 @@ func (s *TestSuite) TestVPEndProposals() { s.Require().NoError(err) s.Require().Equal(resp.GetProposal().FinalTallyResult, spec.tallyRes) + s.Require().Equal(resp.GetProposal().Status, spec.expStatus) + s.Require().Equal(resp.GetProposal().Result, spec.expExecutorResult) }) } } diff --git a/x/group/module/abci.go b/x/group/module/abci.go index e5dac8f387c1..90e900beb0d3 100644 --- a/x/group/module/abci.go +++ b/x/group/module/abci.go @@ -6,5 +6,7 @@ import ( ) func EndBlocker(ctx sdk.Context, k keeper.Keeper) { - k.UpdateTallyOfVPEndProposals(ctx) + if err := k.UpdateTallyOfVPEndProposals(ctx); err != nil { + panic(err) + } } From 2134c69795359ce3309f395b65bf97d0733849d2 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Mar 2022 11:22:56 +0530 Subject: [PATCH 12/17] fix review changes --- x/group/keeper/keeper.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index ab542d1d784a..540b80b111e9 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -68,7 +68,7 @@ type Keeper struct { proposalTable orm.AutoUInt64Table proposalByGroupPolicyIndex orm.Index proposalByProposerIndex orm.Index - ProposalsByVotingPeriodEnd orm.Index + proposalsByVotingPeriodEnd orm.Index // Vote Table voteTable orm.PrimaryKeyTable @@ -184,7 +184,7 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddle if err != nil { panic(err.Error()) } - k.ProposalsByVotingPeriodEnd, err = orm.NewIndex(proposalTable, ProposalsByVotingPeriodEndPrefix, func(value interface{}) ([]interface{}, error) { + k.proposalsByVotingPeriodEnd, err = orm.NewIndex(proposalTable, ProposalsByVotingPeriodEndPrefix, func(value interface{}) ([]interface{}, error) { votingPeriodEnd := value.(*group.Proposal).VotingPeriodEnd return []interface{}{sdk.FormatTimeBytes(votingPeriodEnd)}, nil }, []byte{}) @@ -241,9 +241,9 @@ func (k Keeper) GetGroupSequence(ctx sdk.Context) uint64 { return k.groupTable.Sequence().CurVal(ctx.KVStore(k.key)) } -func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group.Proposal) (stop bool)) error { +func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group.Proposal) (bool, error)) error { timeBytes := sdk.FormatTimeBytes(ctx.BlockTime()) - it, err := k.ProposalsByVotingPeriodEnd.PrefixScan(ctx.KVStore(k.key), nil, timeBytes) + it, err := k.proposalsByVotingPeriodEnd.PrefixScan(ctx.KVStore(k.key), nil, timeBytes) if err != nil { return err @@ -260,40 +260,41 @@ func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group. return err } - if cb(proposal) { + stop, err := cb(proposal) + if stop { break } + if err != nil { + return err + } } return nil } func (k Keeper) UpdateTallyOfVPEndProposals(ctx sdk.Context) error { - k.iterateProposalsByVPEnd(ctx, func(proposal group.Proposal) (stop bool) { + k.iterateProposalsByVPEnd(ctx, func(proposal group.Proposal) (bool, error) { policyInfo, err := k.getGroupPolicyInfo(ctx, proposal.Address) if err != nil { - return true + return true, err } electorate, err := k.getGroupInfo(ctx, policyInfo.GroupId) if err != nil { - return true + return true, err } err = k.doTallyAndUpdate(ctx, &proposal, electorate, policyInfo) if err != nil { - return true + return true, err } - storeUpdates := func() error { - if err := k.proposalTable.Update(ctx.KVStore(k.key), proposal.Id, &proposal); err != nil { - return err - } - return nil + if err := k.proposalTable.Update(ctx.KVStore(k.key), proposal.Id, &proposal); err != nil { + return true, err } - err = storeUpdates() - return err != nil + + return false, nil }) return nil From 8ca4755b0feec180f866ffbef1889697d3a69c7b Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Mar 2022 11:26:51 +0530 Subject: [PATCH 13/17] update `iterateProposalsByVPEnd` --- x/group/keeper/keeper.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 540b80b111e9..8716dfda3c06 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -262,9 +262,6 @@ func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group. stop, err := cb(proposal) if stop { - break - } - if err != nil { return err } } From 0655f00ddf470c9e90f4c1ea755a882aae172394 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Mar 2022 11:29:25 +0530 Subject: [PATCH 14/17] update keeper --- x/group/keeper/keeper.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/group/keeper/keeper.go b/x/group/keeper/keeper.go index 8716dfda3c06..103a9b86a39b 100644 --- a/x/group/keeper/keeper.go +++ b/x/group/keeper/keeper.go @@ -261,9 +261,12 @@ func (k Keeper) iterateProposalsByVPEnd(ctx sdk.Context, cb func(proposal group. } stop, err := cb(proposal) - if stop { + if err != nil { return err } + if stop { + break + } } return nil From b21496787a27aea1673d36ad50d521695058f9d1 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 10 Mar 2022 10:19:38 +0530 Subject: [PATCH 15/17] review changes --- x/group/keeper/keeper_test.go | 2 +- x/group/module/abci_test.go | 233 ++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 x/group/module/abci_test.go diff --git a/x/group/keeper/keeper_test.go b/x/group/keeper/keeper_test.go index 0d090c64bca8..06f0c5c2e21c 100644 --- a/x/group/keeper/keeper_test.go +++ b/x/group/keeper/keeper_test.go @@ -2446,7 +2446,7 @@ func (s *TestSuite) TestExecProposal() { } } -func (s *TestSuite) TestVPEndProposals() { +func (s *TestSuite) TestProposalsByVPEnd() { addrs := s.addrs addr2 := addrs[1] groupPolicy := s.groupPolicyAddr diff --git a/x/group/module/abci_test.go b/x/group/module/abci_test.go new file mode 100644 index 000000000000..04a0bb9acdf9 --- /dev/null +++ b/x/group/module/abci_test.go @@ -0,0 +1,233 @@ +package module_test + +import ( + "context" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/simapp" + "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/module" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestProposalsByVPEnd(t *testing.T) { + app := simapp.Setup(t, false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + addrs := simapp.AddTestAddrsIncremental(app, ctx, 4, types.NewInt(30000000)) + + // Initial group, group policy and balance setup + members := []group.Member{ + {Address: addrs[1].String(), Weight: "1"}, {Address: addrs[2].String(), Weight: "2"}, + } + + groupRes, err := app.GroupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{ + Admin: addrs[0].String(), + Members: members, + }) + + require.NoError(t, err) + groupID := groupRes.GroupId + + policy := group.NewThresholdDecisionPolicy( + "2", + time.Second, + 0, + ) + + policyReq := &group.MsgCreateGroupPolicy{ + Admin: addrs[0].String(), + GroupId: groupID, + } + + err = policyReq.SetDecisionPolicy(policy) + require.NoError(t, err) + policyRes, err := app.GroupKeeper.CreateGroupPolicy(ctx, policyReq) + require.NoError(t, err) + + groupPolicyAddr, err := types.AccAddressFromBech32(policyRes.Address) + require.NoError(t, err) + + votingPeriod := policy.GetVotingPeriod() + now := time.Now() + + msgSend := &banktypes.MsgSend{ + FromAddress: groupPolicyAddr.String(), + ToAddress: addrs[3].String(), + Amount: types.Coins{types.NewInt64Coin("test", 100)}, + } + + proposers := []string{addrs[2].String()} + + specs := map[string]struct { + preRun func(sdkCtx types.Context) uint64 + proposalId uint64 + admin string + expErrMsg string + newCtx types.Context + tallyRes group.TallyResult + expStatus group.ProposalStatus + expExecutorResult group.ProposalResult + }{ + "tally updated after voting power end": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposal(app, sdkCtx, []types.Msg{msgSend}, proposers, groupPolicyAddr) + require.NoError(t, err) + return pId + }, + admin: proposers[0], + newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, + }, + "tally within voting period": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposal(app, sdkCtx, []types.Msg{msgSend}, proposers, groupPolicyAddr) + require.NoError(t, err) + + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, + }, + "tally within voting period(with votes)": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposalAndVote(app, ctx, []types.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES) + require.NoError(t, err) + + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_SUBMITTED, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, + }, + "tally after voting period(with votes)": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposalAndVote(app, ctx, []types.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES) + require.NoError(t, err) + + return pId + }, + admin: proposers[0], + newCtx: ctx.WithBlockTime(now.Add(votingPeriod).Add(time.Hour)), + tallyRes: group.TallyResult{ + YesCount: "2", + NoCount: "0", + NoWithVetoCount: "0", + AbstainCount: "0", + }, + expStatus: group.PROPOSAL_STATUS_CLOSED, + expExecutorResult: group.PROPOSAL_RESULT_ACCEPTED, + }, + "tally of closed proposal": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposal(app, sdkCtx, []types.Msg{msgSend}, proposers, groupPolicyAddr) + require.NoError(t, err) + + _, err = app.GroupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{ + ProposalId: pId, + Address: groupPolicyAddr.String(), + }) + + require.NoError(t, err) + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_WITHDRAWN, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, + }, + "tally of closed proposal (with votes)": { + preRun: func(sdkCtx types.Context) uint64 { + pId, err := submitProposalAndVote(app, ctx, []types.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES) + require.NoError(t, err) + + _, err = app.GroupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{ + ProposalId: pId, + Address: groupPolicyAddr.String(), + }) + + require.NoError(t, err) + return pId + }, + admin: proposers[0], + newCtx: ctx, + tallyRes: group.DefaultTallyResult(), + expStatus: group.PROPOSAL_STATUS_WITHDRAWN, + expExecutorResult: group.PROPOSAL_RESULT_UNFINALIZED, + }, + } + + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + spec := spec + pId := spec.preRun(ctx) + + module.EndBlocker(spec.newCtx, app.GroupKeeper) + resp, err := app.GroupKeeper.Proposal(spec.newCtx, &group.QueryProposalRequest{ + ProposalId: pId, + }) + + if spec.expErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), spec.expErrMsg) + return + } + + require.NoError(t, err) + require.Equal(t, resp.GetProposal().FinalTallyResult, spec.tallyRes) + require.Equal(t, resp.GetProposal().Status, spec.expStatus) + require.Equal(t, resp.GetProposal().Result, spec.expExecutorResult) + }) + } +} + +func submitProposal( + app *simapp.SimApp, ctx context.Context, msgs []types.Msg, + proposers []string, groupPolicyAddr types.AccAddress) (uint64, error) { + proposalReq := &group.MsgSubmitProposal{ + Address: groupPolicyAddr.String(), + Proposers: proposers, + } + err := proposalReq.SetMsgs(msgs) + if err != nil { + return 0, err + } + + proposalRes, err := app.GroupKeeper.SubmitProposal(ctx, proposalReq) + if err != nil { + return 0, err + } + + return proposalRes.ProposalId, nil +} + +func submitProposalAndVote( + app *simapp.SimApp, ctx context.Context, msgs []types.Msg, + proposers []string, groupPolicyAddr types.AccAddress, voteOption group.VoteOption) (uint64, error) { + myProposalID, err := submitProposal(app, ctx, msgs, proposers, groupPolicyAddr) + if err != nil { + return 0, err + } + + _, err = app.GroupKeeper.Vote(ctx, &group.MsgVote{ + ProposalId: myProposalID, + Voter: proposers[0], + Option: voteOption, + }) + if err != nil { + return 0, err + } + + return myProposalID, nil +} From dcfd2a723cb35a1dcbf397a9d2da9a1a9fb921e0 Mon Sep 17 00:00:00 2001 From: atheeshp <59333759+atheeshp@users.noreply.github.com> Date: Thu, 10 Mar 2022 17:35:44 +0530 Subject: [PATCH 16/17] Update x/group/module/abci_test.go Co-authored-by: Marie Gauthier --- x/group/module/abci_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/group/module/abci_test.go b/x/group/module/abci_test.go index 04a0bb9acdf9..f303a38d0360 100644 --- a/x/group/module/abci_test.go +++ b/x/group/module/abci_test.go @@ -14,7 +14,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) -func TestProposalsByVPEnd(t *testing.T) { +func TestEndBlocker(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) addrs := simapp.AddTestAddrsIncremental(app, ctx, 4, types.NewInt(30000000)) From 50be95be0e1a35f67bdc1cfcd8ee795f9423eb33 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Thu, 10 Mar 2022 13:23:57 +0100 Subject: [PATCH 17/17] Update x/group/module/module.go Co-authored-by: likhita-809 <78951027+likhita-809@users.noreply.github.com> --- x/group/module/module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/group/module/module.go b/x/group/module/module.go index 6832dc1392a9..086728422ed4 100644 --- a/x/group/module/module.go +++ b/x/group/module/module.go @@ -154,7 +154,7 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} -// EndBlock does nothing +// EndBlock implements the group module's EndBlock. func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { EndBlocker(ctx, am.keeper) return []abci.ValidatorUpdate{}