github.com/Finschia/finschia-sdk@v0.48.1/x/gov/keeper/grpc_query.go (about) 1 package keeper 2 3 import ( 4 "context" 5 6 "google.golang.org/grpc/codes" 7 "google.golang.org/grpc/status" 8 9 "github.com/Finschia/finschia-sdk/store/prefix" 10 sdk "github.com/Finschia/finschia-sdk/types" 11 "github.com/Finschia/finschia-sdk/types/query" 12 "github.com/Finschia/finschia-sdk/x/gov/types" 13 ) 14 15 var _ types.QueryServer = Keeper{} 16 17 // Proposal returns proposal details based on ProposalID 18 func (q Keeper) Proposal(c context.Context, req *types.QueryProposalRequest) (*types.QueryProposalResponse, error) { 19 if req == nil { 20 return nil, status.Error(codes.InvalidArgument, "invalid request") 21 } 22 23 if req.ProposalId == 0 { 24 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 25 } 26 27 ctx := sdk.UnwrapSDKContext(c) 28 29 proposal, found := q.GetProposal(ctx, req.ProposalId) 30 if !found { 31 return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) 32 } 33 34 return &types.QueryProposalResponse{Proposal: proposal}, nil 35 } 36 37 // Proposals implements the Query/Proposals gRPC method 38 func (q Keeper) Proposals(c context.Context, req *types.QueryProposalsRequest) (*types.QueryProposalsResponse, error) { 39 var filteredProposals types.Proposals 40 ctx := sdk.UnwrapSDKContext(c) 41 42 store := ctx.KVStore(q.storeKey) 43 proposalStore := prefix.NewStore(store, types.ProposalsKeyPrefix) 44 45 pageRes, err := query.FilteredPaginate(proposalStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { 46 var p types.Proposal 47 if err := q.cdc.Unmarshal(value, &p); err != nil { 48 return false, status.Error(codes.Internal, err.Error()) 49 } 50 51 matchVoter, matchDepositor, matchStatus := true, true, true 52 53 // match status (if supplied/valid) 54 if types.ValidProposalStatus(req.ProposalStatus) { 55 matchStatus = p.Status == req.ProposalStatus 56 } 57 58 // match voter address (if supplied) 59 if len(req.Voter) > 0 { 60 voter, err := sdk.AccAddressFromBech32(req.Voter) 61 if err != nil { 62 return false, err 63 } 64 65 _, matchVoter = q.GetVote(ctx, p.ProposalId, voter) 66 } 67 68 // match depositor (if supplied) 69 if len(req.Depositor) > 0 { 70 depositor, err := sdk.AccAddressFromBech32(req.Depositor) 71 if err != nil { 72 return false, err 73 } 74 _, matchDepositor = q.GetDeposit(ctx, p.ProposalId, depositor) 75 } 76 77 if matchVoter && matchDepositor && matchStatus { 78 if accumulate { 79 filteredProposals = append(filteredProposals, p) 80 } 81 82 return true, nil 83 } 84 85 return false, nil 86 }) 87 if err != nil { 88 return nil, status.Error(codes.Internal, err.Error()) 89 } 90 91 return &types.QueryProposalsResponse{Proposals: filteredProposals, Pagination: pageRes}, nil 92 } 93 94 // Vote returns Voted information based on proposalID, voterAddr 95 func (q Keeper) Vote(c context.Context, req *types.QueryVoteRequest) (*types.QueryVoteResponse, error) { 96 if req == nil { 97 return nil, status.Error(codes.InvalidArgument, "invalid request") 98 } 99 100 if req.ProposalId == 0 { 101 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 102 } 103 104 if req.Voter == "" { 105 return nil, status.Error(codes.InvalidArgument, "empty voter address") 106 } 107 108 ctx := sdk.UnwrapSDKContext(c) 109 110 voter, err := sdk.AccAddressFromBech32(req.Voter) 111 if err != nil { 112 return nil, err 113 } 114 vote, found := q.GetVote(ctx, req.ProposalId, voter) 115 if !found { 116 return nil, status.Errorf(codes.InvalidArgument, 117 "voter: %v not found for proposal: %v", req.Voter, req.ProposalId) 118 } 119 120 return &types.QueryVoteResponse{Vote: vote}, nil 121 } 122 123 // Votes returns single proposal's votes 124 func (q Keeper) Votes(c context.Context, req *types.QueryVotesRequest) (*types.QueryVotesResponse, error) { 125 if req == nil { 126 return nil, status.Error(codes.InvalidArgument, "invalid request") 127 } 128 129 if req.ProposalId == 0 { 130 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 131 } 132 133 var votes types.Votes 134 ctx := sdk.UnwrapSDKContext(c) 135 136 store := ctx.KVStore(q.storeKey) 137 votesStore := prefix.NewStore(store, types.VotesKey(req.ProposalId)) 138 139 pageRes, err := query.Paginate(votesStore, req.Pagination, func(key []byte, value []byte) error { 140 var vote types.Vote 141 if err := q.cdc.Unmarshal(value, &vote); err != nil { 142 return err 143 } 144 populateLegacyOption(&vote) 145 146 votes = append(votes, vote) 147 return nil 148 }) 149 if err != nil { 150 return nil, status.Error(codes.Internal, err.Error()) 151 } 152 153 return &types.QueryVotesResponse{Votes: votes, Pagination: pageRes}, nil 154 } 155 156 // Params queries all params 157 func (q Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { 158 if req == nil { 159 return nil, status.Error(codes.InvalidArgument, "invalid request") 160 } 161 162 ctx := sdk.UnwrapSDKContext(c) 163 164 switch req.ParamsType { 165 case types.ParamDeposit: 166 depositParmas := q.GetDepositParams(ctx) 167 return &types.QueryParamsResponse{DepositParams: depositParmas}, nil 168 169 case types.ParamVoting: 170 votingParmas := q.GetVotingParams(ctx) 171 return &types.QueryParamsResponse{VotingParams: votingParmas}, nil 172 173 case types.ParamTallying: 174 tallyParams := q.GetTallyParams(ctx) 175 return &types.QueryParamsResponse{TallyParams: tallyParams}, nil 176 177 default: 178 return nil, status.Errorf(codes.InvalidArgument, 179 "%s is not a valid parameter type", req.ParamsType) 180 } 181 } 182 183 // Deposit queries single deposit information based proposalID, depositAddr 184 func (q Keeper) Deposit(c context.Context, req *types.QueryDepositRequest) (*types.QueryDepositResponse, error) { 185 if req == nil { 186 return nil, status.Error(codes.InvalidArgument, "invalid request") 187 } 188 189 if req.ProposalId == 0 { 190 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 191 } 192 193 if req.Depositor == "" { 194 return nil, status.Error(codes.InvalidArgument, "empty depositor address") 195 } 196 197 ctx := sdk.UnwrapSDKContext(c) 198 199 depositor, err := sdk.AccAddressFromBech32(req.Depositor) 200 if err != nil { 201 return nil, err 202 } 203 deposit, found := q.GetDeposit(ctx, req.ProposalId, depositor) 204 if !found { 205 return nil, status.Errorf(codes.InvalidArgument, 206 "depositer: %v not found for proposal: %v", req.Depositor, req.ProposalId) 207 } 208 209 return &types.QueryDepositResponse{Deposit: deposit}, nil 210 } 211 212 // Deposits returns single proposal's all deposits 213 func (q Keeper) Deposits(c context.Context, req *types.QueryDepositsRequest) (*types.QueryDepositsResponse, error) { 214 if req == nil { 215 return nil, status.Error(codes.InvalidArgument, "invalid request") 216 } 217 218 if req.ProposalId == 0 { 219 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 220 } 221 222 var deposits types.Deposits 223 ctx := sdk.UnwrapSDKContext(c) 224 225 store := ctx.KVStore(q.storeKey) 226 depositStore := prefix.NewStore(store, types.DepositsKey(req.ProposalId)) 227 228 pageRes, err := query.Paginate(depositStore, req.Pagination, func(key []byte, value []byte) error { 229 var deposit types.Deposit 230 if err := q.cdc.Unmarshal(value, &deposit); err != nil { 231 return err 232 } 233 234 deposits = append(deposits, deposit) 235 return nil 236 }) 237 if err != nil { 238 return nil, status.Error(codes.Internal, err.Error()) 239 } 240 241 return &types.QueryDepositsResponse{Deposits: deposits, Pagination: pageRes}, nil 242 } 243 244 // TallyResult queries the tally of a proposal vote 245 func (q Keeper) TallyResult(c context.Context, req *types.QueryTallyResultRequest) (*types.QueryTallyResultResponse, error) { 246 if req == nil { 247 return nil, status.Error(codes.InvalidArgument, "invalid request") 248 } 249 250 if req.ProposalId == 0 { 251 return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") 252 } 253 254 ctx := sdk.UnwrapSDKContext(c) 255 256 proposal, ok := q.GetProposal(ctx, req.ProposalId) 257 if !ok { 258 return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) 259 } 260 261 var tallyResult types.TallyResult 262 263 switch { 264 case proposal.Status == types.StatusDepositPeriod: 265 tallyResult = types.EmptyTallyResult() 266 267 case proposal.Status == types.StatusPassed || proposal.Status == types.StatusRejected: 268 tallyResult = proposal.FinalTallyResult 269 270 default: 271 // proposal is in voting period 272 _, _, tallyResult = q.Tally(ctx, proposal) 273 } 274 275 return &types.QueryTallyResultResponse{Tally: tallyResult}, nil 276 }