github.com/Finschia/finschia-sdk@v0.48.1/x/foundation/keeper/internal/msg_server.go (about) 1 package internal 2 3 import ( 4 "context" 5 6 sdk "github.com/Finschia/finschia-sdk/types" 7 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 8 "github.com/Finschia/finschia-sdk/x/foundation" 9 ) 10 11 const gasCostPerIteration = uint64(20) 12 13 type msgServer struct { 14 keeper Keeper 15 } 16 17 // NewMsgServer returns an implementation of the token MsgServer interface 18 // for the provided Keeper. 19 func NewMsgServer(keeper Keeper) foundation.MsgServer { 20 return &msgServer{ 21 keeper: keeper, 22 } 23 } 24 25 var _ foundation.MsgServer = msgServer{} 26 27 // FundTreasury defines a method to fund the treasury. 28 func (s msgServer) FundTreasury(c context.Context, req *foundation.MsgFundTreasury) (*foundation.MsgFundTreasuryResponse, error) { 29 ctx := sdk.UnwrapSDKContext(c) 30 from := sdk.MustAccAddressFromBech32(req.From) 31 if err := s.keeper.FundTreasury(ctx, from, req.Amount); err != nil { 32 return nil, err 33 } 34 35 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventFundTreasury{ 36 From: req.From, 37 Amount: req.Amount, 38 }); err != nil { 39 panic(err) 40 } 41 42 return &foundation.MsgFundTreasuryResponse{}, nil 43 } 44 45 // WithdrawFromTreasury defines a method to withdraw coins from the treasury. 46 func (s msgServer) WithdrawFromTreasury(c context.Context, req *foundation.MsgWithdrawFromTreasury) (*foundation.MsgWithdrawFromTreasuryResponse, error) { 47 ctx := sdk.UnwrapSDKContext(c) 48 49 if err := s.keeper.validateAuthority(req.Authority); err != nil { 50 return nil, err 51 } 52 53 to := sdk.MustAccAddressFromBech32(req.To) 54 if err := s.keeper.Accept(ctx, to, req); err != nil { 55 return nil, err 56 } 57 58 if err := s.keeper.WithdrawFromTreasury(ctx, to, req.Amount); err != nil { 59 return nil, err 60 } 61 62 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventWithdrawFromTreasury{ 63 To: req.To, 64 Amount: req.Amount, 65 }); err != nil { 66 panic(err) 67 } 68 69 return &foundation.MsgWithdrawFromTreasuryResponse{}, nil 70 } 71 72 func (s msgServer) UpdateMembers(c context.Context, req *foundation.MsgUpdateMembers) (*foundation.MsgUpdateMembersResponse, error) { 73 ctx := sdk.UnwrapSDKContext(c) 74 75 if err := s.keeper.validateAuthority(req.Authority); err != nil { 76 return nil, err 77 } 78 79 if err := s.keeper.UpdateMembers(ctx, req.MemberUpdates); err != nil { 80 return nil, err 81 } 82 83 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventUpdateMembers{ 84 MemberUpdates: req.MemberUpdates, 85 }); err != nil { 86 panic(err) 87 } 88 89 return &foundation.MsgUpdateMembersResponse{}, nil 90 } 91 92 func (s msgServer) UpdateDecisionPolicy(c context.Context, req *foundation.MsgUpdateDecisionPolicy) (*foundation.MsgUpdateDecisionPolicyResponse, error) { 93 ctx := sdk.UnwrapSDKContext(c) 94 95 if err := s.keeper.validateAuthority(req.Authority); err != nil { 96 return nil, err 97 } 98 99 policy := req.GetDecisionPolicy() 100 if err := s.keeper.UpdateDecisionPolicy(ctx, policy); err != nil { 101 return nil, err 102 } 103 104 event := &foundation.EventUpdateDecisionPolicy{} 105 if err := event.SetDecisionPolicy(policy); err != nil { 106 return nil, err 107 } 108 if err := ctx.EventManager().EmitTypedEvent(event); err != nil { 109 panic(err) 110 } 111 112 return &foundation.MsgUpdateDecisionPolicyResponse{}, nil 113 } 114 115 func (s msgServer) SubmitProposal(c context.Context, req *foundation.MsgSubmitProposal) (*foundation.MsgSubmitProposalResponse, error) { 116 ctx := sdk.UnwrapSDKContext(c) 117 118 if err := s.keeper.validateMembers(ctx, req.Proposers); err != nil { 119 return nil, err 120 } 121 122 id, err := s.keeper.SubmitProposal(ctx, req.Proposers, req.Metadata, req.GetMsgs()) 123 if err != nil { 124 return nil, err 125 } 126 127 proposal, err := s.keeper.GetProposal(ctx, *id) 128 if err != nil { 129 panic(err) 130 } 131 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventSubmitProposal{ 132 Proposal: *proposal, 133 }); err != nil { 134 panic(err) 135 } 136 137 // Try to execute proposal immediately 138 if req.Exec == foundation.Exec_EXEC_TRY { 139 // Consider proposers as Yes votes 140 for _, proposer := range req.Proposers { 141 ctx.GasMeter().ConsumeGas(gasCostPerIteration, "vote on proposal") 142 143 vote := foundation.Vote{ 144 ProposalId: *id, 145 Voter: proposer, 146 Option: foundation.VOTE_OPTION_YES, 147 } 148 err = s.keeper.Vote(ctx, vote) 149 if err != nil { 150 return &foundation.MsgSubmitProposalResponse{ProposalId: *id}, sdkerrors.Wrap(err, "The proposal was created but failed on vote") 151 } 152 } 153 154 // Then try to execute the proposal 155 if err = s.keeper.Exec(ctx, *id); err != nil { 156 return &foundation.MsgSubmitProposalResponse{ProposalId: *id}, sdkerrors.Wrap(err, "The proposal was created but failed on exec") 157 } 158 } 159 160 return &foundation.MsgSubmitProposalResponse{ProposalId: *id}, nil 161 } 162 163 func (s msgServer) WithdrawProposal(c context.Context, req *foundation.MsgWithdrawProposal) (*foundation.MsgWithdrawProposalResponse, error) { 164 ctx := sdk.UnwrapSDKContext(c) 165 id := req.ProposalId 166 167 proposal, err := s.keeper.GetProposal(ctx, id) 168 if err != nil { 169 return nil, err 170 } 171 172 // authority may withdraw any proposal. 173 if err := s.keeper.validateAuthority(req.Address); err != nil { 174 // check whether the address is in proposers list. 175 if err := validateActorForProposal(req.Address, *proposal); err != nil { 176 return nil, err 177 } 178 } 179 180 if err := s.keeper.WithdrawProposal(ctx, id); err != nil { 181 return nil, err 182 } 183 184 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventWithdrawProposal{ 185 ProposalId: id, 186 }); err != nil { 187 panic(err) 188 } 189 190 return &foundation.MsgWithdrawProposalResponse{}, nil 191 } 192 193 func (s msgServer) Vote(c context.Context, req *foundation.MsgVote) (*foundation.MsgVoteResponse, error) { 194 ctx := sdk.UnwrapSDKContext(c) 195 196 if err := s.keeper.validateMembers(ctx, []string{req.Voter}); err != nil { 197 return nil, err 198 } 199 200 vote := foundation.Vote{ 201 ProposalId: req.ProposalId, 202 Voter: req.Voter, 203 Option: req.Option, 204 Metadata: req.Metadata, 205 } 206 if err := s.keeper.Vote(ctx, vote); err != nil { 207 return nil, err 208 } 209 210 // Try to execute proposal immediately 211 if req.Exec == foundation.Exec_EXEC_TRY { 212 if err := s.keeper.Exec(ctx, req.ProposalId); err != nil { 213 return nil, err 214 } 215 } 216 217 return &foundation.MsgVoteResponse{}, nil 218 } 219 220 func (s msgServer) Exec(c context.Context, req *foundation.MsgExec) (*foundation.MsgExecResponse, error) { 221 ctx := sdk.UnwrapSDKContext(c) 222 223 if err := s.keeper.validateMembers(ctx, []string{req.Signer}); err != nil { 224 return nil, err 225 } 226 227 if err := s.keeper.Exec(ctx, req.ProposalId); err != nil { 228 return nil, err 229 } 230 231 return &foundation.MsgExecResponse{}, nil 232 } 233 234 func (s msgServer) LeaveFoundation(c context.Context, req *foundation.MsgLeaveFoundation) (*foundation.MsgLeaveFoundationResponse, error) { 235 ctx := sdk.UnwrapSDKContext(c) 236 237 if err := s.keeper.validateMembers(ctx, []string{req.Address}); err != nil { 238 return nil, err 239 } 240 241 update := foundation.MemberRequest{ 242 Address: req.Address, 243 Remove: true, 244 } 245 if err := s.keeper.UpdateMembers(ctx, []foundation.MemberRequest{update}); err != nil { 246 return nil, err 247 } 248 249 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventLeaveFoundation{ 250 Address: req.Address, 251 }); err != nil { 252 panic(err) 253 } 254 255 return &foundation.MsgLeaveFoundationResponse{}, nil 256 } 257 258 func (s msgServer) UpdateCensorship(c context.Context, req *foundation.MsgUpdateCensorship) (*foundation.MsgUpdateCensorshipResponse, error) { 259 ctx := sdk.UnwrapSDKContext(c) 260 261 url := req.Censorship.MsgTypeUrl 262 if err := s.keeper.validateCensorshipAuthority(ctx, url, req.Authority); err != nil { 263 return nil, err 264 } 265 266 if err := s.keeper.UpdateCensorship(ctx, req.Censorship); err != nil { 267 return nil, err 268 } 269 270 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventUpdateCensorship{ 271 Censorship: req.Censorship, 272 }); err != nil { 273 panic(err) 274 } 275 276 return &foundation.MsgUpdateCensorshipResponse{}, nil 277 } 278 279 func (s msgServer) Grant(c context.Context, req *foundation.MsgGrant) (*foundation.MsgGrantResponse, error) { 280 ctx := sdk.UnwrapSDKContext(c) 281 282 authorization := req.GetAuthorization() 283 284 url := authorization.MsgTypeURL() 285 if err := s.keeper.validateCensorshipAuthority(ctx, url, req.Authority); err != nil { 286 return nil, err 287 } 288 289 grantee := sdk.MustAccAddressFromBech32(req.Grantee) 290 if err := s.keeper.Grant(ctx, grantee, authorization); err != nil { 291 return nil, err 292 } 293 294 return &foundation.MsgGrantResponse{}, nil 295 } 296 297 func (s msgServer) Revoke(c context.Context, req *foundation.MsgRevoke) (*foundation.MsgRevokeResponse, error) { 298 ctx := sdk.UnwrapSDKContext(c) 299 300 url := req.MsgTypeUrl 301 if err := s.keeper.validateCensorshipAuthority(ctx, url, req.Authority); err != nil { 302 return nil, err 303 } 304 305 grantee := sdk.MustAccAddressFromBech32(req.Grantee) 306 if err := s.keeper.Revoke(ctx, grantee, req.MsgTypeUrl); err != nil { 307 return nil, err 308 } 309 310 return &foundation.MsgRevokeResponse{}, nil 311 }