feat(x/gov): multiple choice proposals (#18762)

This commit is contained in:
Julien Robert 2024-01-08 12:55:37 +01:00 committed by GitHub
parent 6848448dc2
commit 41c84d6190
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 6606 additions and 954 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,15 +21,16 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Query_Constitution_FullMethodName = "/cosmos.gov.v1.Query/Constitution"
Query_Proposal_FullMethodName = "/cosmos.gov.v1.Query/Proposal"
Query_Proposals_FullMethodName = "/cosmos.gov.v1.Query/Proposals"
Query_Vote_FullMethodName = "/cosmos.gov.v1.Query/Vote"
Query_Votes_FullMethodName = "/cosmos.gov.v1.Query/Votes"
Query_Params_FullMethodName = "/cosmos.gov.v1.Query/Params"
Query_Deposit_FullMethodName = "/cosmos.gov.v1.Query/Deposit"
Query_Deposits_FullMethodName = "/cosmos.gov.v1.Query/Deposits"
Query_TallyResult_FullMethodName = "/cosmos.gov.v1.Query/TallyResult"
Query_Constitution_FullMethodName = "/cosmos.gov.v1.Query/Constitution"
Query_Proposal_FullMethodName = "/cosmos.gov.v1.Query/Proposal"
Query_Proposals_FullMethodName = "/cosmos.gov.v1.Query/Proposals"
Query_Vote_FullMethodName = "/cosmos.gov.v1.Query/Vote"
Query_Votes_FullMethodName = "/cosmos.gov.v1.Query/Votes"
Query_Params_FullMethodName = "/cosmos.gov.v1.Query/Params"
Query_Deposit_FullMethodName = "/cosmos.gov.v1.Query/Deposit"
Query_Deposits_FullMethodName = "/cosmos.gov.v1.Query/Deposits"
Query_TallyResult_FullMethodName = "/cosmos.gov.v1.Query/TallyResult"
Query_ProposalVoteOptions_FullMethodName = "/cosmos.gov.v1.Query/ProposalVoteOptions"
)
// QueryClient is the client API for Query service.
@ -54,6 +55,8 @@ type QueryClient interface {
Deposits(ctx context.Context, in *QueryDepositsRequest, opts ...grpc.CallOption) (*QueryDepositsResponse, error)
// TallyResult queries the tally of a proposal vote.
TallyResult(ctx context.Context, in *QueryTallyResultRequest, opts ...grpc.CallOption) (*QueryTallyResultResponse, error)
// ProposalVoteOptions queries the valid voting options for a proposal.
ProposalVoteOptions(ctx context.Context, in *QueryProposalVoteOptionsRequest, opts ...grpc.CallOption) (*QueryProposalVoteOptionsResponse, error)
}
type queryClient struct {
@ -145,6 +148,15 @@ func (c *queryClient) TallyResult(ctx context.Context, in *QueryTallyResultReque
return out, nil
}
func (c *queryClient) ProposalVoteOptions(ctx context.Context, in *QueryProposalVoteOptionsRequest, opts ...grpc.CallOption) (*QueryProposalVoteOptionsResponse, error) {
out := new(QueryProposalVoteOptionsResponse)
err := c.cc.Invoke(ctx, Query_ProposalVoteOptions_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
// All implementations must embed UnimplementedQueryServer
// for forward compatibility
@ -167,6 +179,8 @@ type QueryServer interface {
Deposits(context.Context, *QueryDepositsRequest) (*QueryDepositsResponse, error)
// TallyResult queries the tally of a proposal vote.
TallyResult(context.Context, *QueryTallyResultRequest) (*QueryTallyResultResponse, error)
// ProposalVoteOptions queries the valid voting options for a proposal.
ProposalVoteOptions(context.Context, *QueryProposalVoteOptionsRequest) (*QueryProposalVoteOptionsResponse, error)
mustEmbedUnimplementedQueryServer()
}
@ -201,6 +215,9 @@ func (UnimplementedQueryServer) Deposits(context.Context, *QueryDepositsRequest)
func (UnimplementedQueryServer) TallyResult(context.Context, *QueryTallyResultRequest) (*QueryTallyResultResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method TallyResult not implemented")
}
func (UnimplementedQueryServer) ProposalVoteOptions(context.Context, *QueryProposalVoteOptionsRequest) (*QueryProposalVoteOptionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ProposalVoteOptions not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
@ -376,6 +393,24 @@ func _Query_TallyResult_Handler(srv interface{}, ctx context.Context, dec func(i
return interceptor(ctx, in, info, handler)
}
func _Query_ProposalVoteOptions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryProposalVoteOptionsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).ProposalVoteOptions(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_ProposalVoteOptions_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).ProposalVoteOptions(ctx, req.(*QueryProposalVoteOptionsRequest))
}
return interceptor(ctx, in, info, handler)
}
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -419,6 +454,10 @@ var Query_ServiceDesc = grpc.ServiceDesc{
MethodName: "TallyResult",
Handler: _Query_TallyResult_Handler,
},
{
MethodName: "ProposalVoteOptions",
Handler: _Query_ProposalVoteOptions_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/gov/v1/query.proto",

File diff suppressed because it is too large Load Diff

View File

@ -21,13 +21,14 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Msg_SubmitProposal_FullMethodName = "/cosmos.gov.v1.Msg/SubmitProposal"
Msg_ExecLegacyContent_FullMethodName = "/cosmos.gov.v1.Msg/ExecLegacyContent"
Msg_Vote_FullMethodName = "/cosmos.gov.v1.Msg/Vote"
Msg_VoteWeighted_FullMethodName = "/cosmos.gov.v1.Msg/VoteWeighted"
Msg_Deposit_FullMethodName = "/cosmos.gov.v1.Msg/Deposit"
Msg_UpdateParams_FullMethodName = "/cosmos.gov.v1.Msg/UpdateParams"
Msg_CancelProposal_FullMethodName = "/cosmos.gov.v1.Msg/CancelProposal"
Msg_SubmitProposal_FullMethodName = "/cosmos.gov.v1.Msg/SubmitProposal"
Msg_ExecLegacyContent_FullMethodName = "/cosmos.gov.v1.Msg/ExecLegacyContent"
Msg_Vote_FullMethodName = "/cosmos.gov.v1.Msg/Vote"
Msg_VoteWeighted_FullMethodName = "/cosmos.gov.v1.Msg/VoteWeighted"
Msg_Deposit_FullMethodName = "/cosmos.gov.v1.Msg/Deposit"
Msg_UpdateParams_FullMethodName = "/cosmos.gov.v1.Msg/UpdateParams"
Msg_CancelProposal_FullMethodName = "/cosmos.gov.v1.Msg/CancelProposal"
Msg_SubmitMultipleChoiceProposal_FullMethodName = "/cosmos.gov.v1.Msg/SubmitMultipleChoiceProposal"
)
// MsgClient is the client API for Msg service.
@ -54,6 +55,10 @@ type MsgClient interface {
//
// Since: cosmos-sdk 0.50
CancelProposal(ctx context.Context, in *MsgCancelProposal, opts ...grpc.CallOption) (*MsgCancelProposalResponse, error)
// SubmitMultipleChoiceProposal defines a method to create new multiple choice proposal.
//
// Since: x/gov 1.0.0
SubmitMultipleChoiceProposal(ctx context.Context, in *MsgSubmitMultipleChoiceProposal, opts ...grpc.CallOption) (*MsgSubmitMultipleChoiceProposalResponse, error)
}
type msgClient struct {
@ -127,6 +132,15 @@ func (c *msgClient) CancelProposal(ctx context.Context, in *MsgCancelProposal, o
return out, nil
}
func (c *msgClient) SubmitMultipleChoiceProposal(ctx context.Context, in *MsgSubmitMultipleChoiceProposal, opts ...grpc.CallOption) (*MsgSubmitMultipleChoiceProposalResponse, error) {
out := new(MsgSubmitMultipleChoiceProposalResponse)
err := c.cc.Invoke(ctx, Msg_SubmitMultipleChoiceProposal_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MsgServer is the server API for Msg service.
// All implementations must embed UnimplementedMsgServer
// for forward compatibility
@ -151,6 +165,10 @@ type MsgServer interface {
//
// Since: cosmos-sdk 0.50
CancelProposal(context.Context, *MsgCancelProposal) (*MsgCancelProposalResponse, error)
// SubmitMultipleChoiceProposal defines a method to create new multiple choice proposal.
//
// Since: x/gov 1.0.0
SubmitMultipleChoiceProposal(context.Context, *MsgSubmitMultipleChoiceProposal) (*MsgSubmitMultipleChoiceProposalResponse, error)
mustEmbedUnimplementedMsgServer()
}
@ -179,6 +197,9 @@ func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*
func (UnimplementedMsgServer) CancelProposal(context.Context, *MsgCancelProposal) (*MsgCancelProposalResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CancelProposal not implemented")
}
func (UnimplementedMsgServer) SubmitMultipleChoiceProposal(context.Context, *MsgSubmitMultipleChoiceProposal) (*MsgSubmitMultipleChoiceProposalResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SubmitMultipleChoiceProposal not implemented")
}
func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {}
// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service.
@ -318,6 +339,24 @@ func _Msg_CancelProposal_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
func _Msg_SubmitMultipleChoiceProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgSubmitMultipleChoiceProposal)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).SubmitMultipleChoiceProposal(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_SubmitMultipleChoiceProposal_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).SubmitMultipleChoiceProposal(ctx, req.(*MsgSubmitMultipleChoiceProposal))
}
return interceptor(ctx, in, info, handler)
}
// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -353,6 +392,10 @@ var Msg_ServiceDesc = grpc.ServiceDesc{
MethodName: "CancelProposal",
Handler: _Msg_CancelProposal_Handler,
},
{
MethodName: "SubmitMultipleChoiceProposal",
Handler: _Msg_SubmitMultipleChoiceProposal_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/gov/v1/tx.proto",

View File

@ -87,7 +87,7 @@ Submitting a new multiple choice proposal will use a different message than the
```protobuf
message MsgSubmitMultipleChoiceProposal {
repeated cosmos.base.v1beta1.Coin initial_deposit = 1
repeated cosmos.base.v1beta1.Coin initial_deposit = 1;
string proposer = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string metadata = 3;
string title = 4;

View File

@ -139,7 +139,7 @@ message Proposal {
// proposal_type defines the type of the proposal
//
// Since: cosmos-sdk 0.51
// Since: x/gov v1.0.0
ProposalType proposal_type = 16;
}
@ -164,6 +164,27 @@ enum ProposalStatus {
PROPOSAL_STATUS_FAILED = 5;
}
// ProposalVoteOptions defines the stringified vote options for proposals.
// This allows to support multiple choice options for a given proposal.
//
// Since: x/gov v1.0.0
message ProposalVoteOptions {
// option_one is the first option of the proposal
string option_one = 1;
// option_two is the second option of the proposal
string option_two = 2;
// option_three is the third option of the proposal
string option_three = 3;
// option_four is the fourth option of the proposal
string option_four = 4;
// option_spam is always present for all proposals.
string option_spam = 5;
}
// TallyResult defines a standard tally for a governance proposal.
message TallyResult {
// yes_count is the number of yes votes on a proposal.
@ -314,6 +335,8 @@ message Params {
// If the proposal is cancelled before the max cancel period, the deposit will be returned/burn to the
// depositors, according to the proposal_cancel_ratio and proposal_cancel_dest parameters.
// After the max cancel period, the proposal cannot be cancelled anymore.
//
// Since: x/gov v1.0.0
string proposal_cancel_max_period = 17 [(cosmos_proto.scalar) = "cosmos.Dec"];
// optimistic_authorized_addresses is an optional governance parameter that limits the authorized accounts than can

View File

@ -55,6 +55,11 @@ service Query {
rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) {
option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/tally";
}
// ProposalVoteOptions queries the valid voting options for a proposal.
rpc ProposalVoteOptions(QueryProposalVoteOptionsRequest) returns (QueryProposalVoteOptionsResponse) {
option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/vote_options";
}
}
// QueryConstitutionRequest is the request type for the Query/Constitution RPC method
@ -203,3 +208,15 @@ message QueryTallyResultResponse {
// tally defines the requested tally.
TallyResult tally = 1;
}
// QueryProposalVoteOptionsRequest is the request type for the Query/ProposalVoteOptions RPC method.
message QueryProposalVoteOptionsRequest {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
}
// QueryProposalVoteOptionsResponse is the response type for the Query/ProposalVoteOptions RPC method.
message QueryProposalVoteOptionsResponse {
// vote_options defines the valid voting options for a proposal.
ProposalVoteOptions vote_options = 1;
}

View File

@ -43,6 +43,11 @@ service Msg {
//
// Since: cosmos-sdk 0.50
rpc CancelProposal(MsgCancelProposal) returns (MsgCancelProposalResponse);
// SubmitMultipleChoiceProposal defines a method to create new multiple choice proposal.
//
// Since: x/gov 1.0.0
rpc SubmitMultipleChoiceProposal(MsgSubmitMultipleChoiceProposal) returns (MsgSubmitMultipleChoiceProposalResponse);
}
// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary
@ -89,7 +94,7 @@ message MsgSubmitProposal {
// proposal_type defines the type of proposal
// When not set defaults to PROPOSAL_TYPE_STANDARD
//
// Since: cosmos-sdk 0.51
// Since: x/gov v1.0.0
ProposalType proposal_type = 8;
}
@ -220,3 +225,41 @@ message MsgCancelProposalResponse {
// canceled_height defines the block height at which the proposal is canceled.
uint64 canceled_height = 3;
}
// MsgSubmitMultipleChoiceProposal defines a message to submit a multiple choice proposal.
//
// Since: x/gov 1.0.0
message MsgSubmitMultipleChoiceProposal {
option (cosmos.msg.v1.signer) = "proposer";
// initial_deposit is the deposit value that must be paid at proposal submission.
repeated cosmos.base.v1beta1.Coin initial_deposit = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(amino.dont_omitempty) = true,
(amino.encoding) = "legacy_coins"
];
// proposer is the account address of the proposer.
string proposer = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// metadata is any arbitrary metadata attached to the proposal.
string metadata = 3;
// title is the title of the proposal.
string title = 4;
// summary is the summary of the proposal
string summary = 5;
// vote_options defines the vote options for the proposal.
ProposalVoteOptions vote_options = 6;
}
// MsgSubmitMultipleChoiceProposalResponse defines the Msg/SubmitMultipleChoiceProposal response type.
//
// Since: x/gov 1.0.0
message MsgSubmitMultipleChoiceProposalResponse {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
}

View File

@ -30,6 +30,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#18532](https://github.com/cosmos/cosmos-sdk/pull/18532) Add SPAM vote to proposals.
* [#18532](https://github.com/cosmos/cosmos-sdk/pull/18532) Add proposal types to proposals.
* [#18620](https://github.com/cosmos/cosmos-sdk/pull/18620) Add optimistic proposals.
* [#18762](https://github.com/cosmos/cosmos-sdk/pull/18762) Add multiple choice proposals.
### Improvements

View File

@ -461,12 +461,21 @@ More information on how to submit proposals in the [client section](#client).
### Proposal Submission
Proposals can be submitted by any account via a `MsgSubmitProposal` transaction.
Proposals can be submitted by any account via a `MsgSubmitProposal` or a `MsgSubmitMultipleChoiceProposal` transaction.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L42-L69
```
:::note
A multiple choice proposal is a proposal where the voting options can be defined by the proposer.
It cannot have messages to execute. It is only a text proposal.
:::
:::warning
Submitting a multiple choice proposal using `MsgSubmitProposal` is invalid, as vote options cannot be defined.
:::
All `sdk.Msgs` passed into the `messages` field of a `MsgSubmitProposal` message
must be registered in the app's `MsgServiceRouter`. Each of these messages must
have one signer, namely the gov module account. And finally, the metadata length
@ -540,7 +549,7 @@ The governance module emits the following events:
### Handlers
#### MsgSubmitProposal
#### MsgSubmitProposal, MsgSubmitMultipleChoiceProposal
| Type | Attribute Key | Attribute Value |
| ------------------- | ------------------- | --------------- |

View File

@ -17,17 +17,17 @@ import (
)
// SetDeposit sets a Deposit to the gov store
func (keeper Keeper) SetDeposit(ctx context.Context, deposit v1.Deposit) error {
depositor, err := keeper.authKeeper.AddressCodec().StringToBytes(deposit.Depositor)
func (k Keeper) SetDeposit(ctx context.Context, deposit v1.Deposit) error {
depositor, err := k.authKeeper.AddressCodec().StringToBytes(deposit.Depositor)
if err != nil {
return err
}
return keeper.Deposits.Set(ctx, collections.Join(deposit.ProposalId, sdk.AccAddress(depositor)), deposit)
return k.Deposits.Set(ctx, collections.Join(deposit.ProposalId, sdk.AccAddress(depositor)), deposit)
}
// GetDeposits returns all the deposits of a proposal
func (keeper Keeper) GetDeposits(ctx context.Context, proposalID uint64) (deposits v1.Deposits, err error) {
err = keeper.IterateDeposits(ctx, proposalID, func(_ collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) {
func (k Keeper) GetDeposits(ctx context.Context, proposalID uint64) (deposits v1.Deposits, err error) {
err = k.IterateDeposits(ctx, proposalID, func(_ collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) {
deposits = append(deposits, &deposit)
return false, nil
})
@ -35,23 +35,23 @@ func (keeper Keeper) GetDeposits(ctx context.Context, proposalID uint64) (deposi
}
// DeleteAndBurnDeposits deletes and burns all the deposits on a specific proposal.
func (keeper Keeper) DeleteAndBurnDeposits(ctx context.Context, proposalID uint64) error {
func (k Keeper) DeleteAndBurnDeposits(ctx context.Context, proposalID uint64) error {
coinsToBurn := sdk.NewCoins()
err := keeper.IterateDeposits(ctx, proposalID, func(key collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (stop bool, err error) {
err := k.IterateDeposits(ctx, proposalID, func(key collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (stop bool, err error) {
coinsToBurn = coinsToBurn.Add(deposit.Amount...)
return false, keeper.Deposits.Remove(ctx, key)
return false, k.Deposits.Remove(ctx, key)
})
if err != nil {
return err
}
return keeper.bankKeeper.BurnCoins(ctx, keeper.authKeeper.GetModuleAddress(types.ModuleName), coinsToBurn)
return k.bankKeeper.BurnCoins(ctx, k.authKeeper.GetModuleAddress(types.ModuleName), coinsToBurn)
}
// IterateDeposits iterates over all the proposals deposits and performs a callback function
func (keeper Keeper) IterateDeposits(ctx context.Context, proposalID uint64, cb func(key collections.Pair[uint64, sdk.AccAddress], value v1.Deposit) (bool, error)) error {
func (k Keeper) IterateDeposits(ctx context.Context, proposalID uint64, cb func(key collections.Pair[uint64, sdk.AccAddress], value v1.Deposit) (bool, error)) error {
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposalID)
if err := keeper.Deposits.Walk(ctx, rng, cb); err != nil {
if err := k.Deposits.Walk(ctx, rng, cb); err != nil {
return err
}
@ -60,9 +60,9 @@ func (keeper Keeper) IterateDeposits(ctx context.Context, proposalID uint64, cb
// AddDeposit adds or updates a deposit of a specific depositor on a specific proposal.
// Activates voting period when appropriate and returns true in that case, else returns false.
func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) {
func (k Keeper) AddDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) {
// Checks to see if proposal exists
proposal, err := keeper.Proposals.Get(ctx, proposalID)
proposal, err := k.Proposals.Get(ctx, proposalID)
if err != nil {
return false, err
}
@ -73,7 +73,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
}
// Check coins to be deposited match the proposal's deposit params
params, err := keeper.Params.Get(ctx)
params, err := k.Params.Get(ctx)
if err != nil {
return false, err
}
@ -85,7 +85,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
}
// the deposit must only contain valid denoms (listed in the min deposit param)
if err := keeper.validateDepositDenom(ctx, params, depositAmount); err != nil {
if err := k.validateDepositDenom(ctx, params, depositAmount); err != nil {
return false, err
}
@ -121,14 +121,14 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
}
// update the governance module's account coins pool
err = keeper.bankKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount)
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount)
if err != nil {
return false, err
}
// Update proposal
proposal.TotalDeposit = sdk.NewCoins(proposal.TotalDeposit...).Add(depositAmount...)
err = keeper.SetProposal(ctx, proposal)
err = k.SetProposal(ctx, proposal)
if err != nil {
return false, err
}
@ -136,7 +136,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
// Check if deposit has provided sufficient total funds to transition the proposal into the voting period
activatedVotingPeriod := false
if proposal.Status == v1.StatusDepositPeriod && sdk.NewCoins(proposal.TotalDeposit...).IsAllGTE(minDepositAmount) {
err = keeper.ActivateVotingPeriod(ctx, proposal)
err = k.ActivateVotingPeriod(ctx, proposal)
if err != nil {
return false, err
}
@ -145,7 +145,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
}
// Add or update deposit object
deposit, err := keeper.Deposits.Get(ctx, collections.Join(proposalID, depositorAddr))
deposit, err := k.Deposits.Get(ctx, collections.Join(proposalID, depositorAddr))
switch {
case err == nil:
// deposit exists
@ -159,7 +159,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
}
// called when deposit has been added to a proposal, however the proposal may not be active
err = keeper.Hooks().AfterProposalDeposit(ctx, proposalID, depositorAddr)
err = k.Hooks().AfterProposalDeposit(ctx, proposalID, depositorAddr)
if err != nil {
return false, err
}
@ -173,7 +173,7 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
),
)
err = keeper.SetDeposit(ctx, deposit)
err = k.SetDeposit(ctx, deposit)
if err != nil {
return false, err
}
@ -184,17 +184,17 @@ func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, deposito
// ChargeDeposit will charge proposal cancellation fee (deposits * proposal_cancel_burn_rate) and
// send to a destAddress if defined or burn otherwise.
// Remaining funds are send back to the depositor.
func (keeper Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destAddress, proposalCancelRate string) error {
func (k Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destAddress, proposalCancelRate string) error {
rate := sdkmath.LegacyMustNewDecFromStr(proposalCancelRate)
var cancellationCharges sdk.Coins
deposits, err := keeper.GetDeposits(ctx, proposalID)
deposits, err := k.GetDeposits(ctx, proposalID)
if err != nil {
return err
}
for _, deposit := range deposits {
depositerAddress, err := keeper.authKeeper.AddressCodec().StringToBytes(deposit.Depositor)
depositerAddress, err := k.authKeeper.AddressCodec().StringToBytes(deposit.Depositor)
if err != nil {
return err
}
@ -219,14 +219,14 @@ func (keeper Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destA
}
if !remainingAmount.IsZero() {
err := keeper.bankKeeper.SendCoinsFromModuleToAccount(
err := k.bankKeeper.SendCoinsFromModuleToAccount(
ctx, types.ModuleName, depositerAddress, remainingAmount,
)
if err != nil {
return err
}
}
err = keeper.Deposits.Remove(ctx, collections.Join(deposit.ProposalId, sdk.AccAddress(depositerAddress)))
err = k.Deposits.Remove(ctx, collections.Join(deposit.ProposalId, sdk.AccAddress(depositerAddress)))
if err != nil {
return err
}
@ -235,25 +235,25 @@ func (keeper Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destA
// burn the cancellation fee or send the cancellation charges to destination address.
if !cancellationCharges.IsZero() {
// get the pool module account address
poolAddress := keeper.authKeeper.GetModuleAddress(pooltypes.ModuleName)
poolAddress := k.authKeeper.GetModuleAddress(pooltypes.ModuleName)
switch {
case destAddress == "":
// burn the cancellation charges from deposits
err := keeper.bankKeeper.BurnCoins(ctx, keeper.authKeeper.GetModuleAddress(types.ModuleName), cancellationCharges)
err := k.bankKeeper.BurnCoins(ctx, k.authKeeper.GetModuleAddress(types.ModuleName), cancellationCharges)
if err != nil {
return err
}
case poolAddress.String() == destAddress:
err := keeper.poolKeeper.FundCommunityPool(ctx, cancellationCharges, keeper.ModuleAccountAddress())
err := k.poolKeeper.FundCommunityPool(ctx, cancellationCharges, k.ModuleAccountAddress())
if err != nil {
return err
}
default:
destAccAddress, err := keeper.authKeeper.AddressCodec().StringToBytes(destAddress)
destAccAddress, err := k.authKeeper.AddressCodec().StringToBytes(destAddress)
if err != nil {
return err
}
err = keeper.bankKeeper.SendCoinsFromModuleToAccount(
err = k.bankKeeper.SendCoinsFromModuleToAccount(
ctx, types.ModuleName, destAccAddress, cancellationCharges,
)
if err != nil {
@ -266,14 +266,14 @@ func (keeper Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destA
}
// RefundAndDeleteDeposits refunds and deletes all the deposits on a specific proposal.
func (keeper Keeper) RefundAndDeleteDeposits(ctx context.Context, proposalID uint64) error {
return keeper.IterateDeposits(ctx, proposalID, func(key collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) {
func (k Keeper) RefundAndDeleteDeposits(ctx context.Context, proposalID uint64) error {
return k.IterateDeposits(ctx, proposalID, func(key collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) {
depositor := key.K2()
err := keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, deposit.Amount)
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, deposit.Amount)
if err != nil {
return false, err
}
err = keeper.Deposits.Remove(ctx, key)
err = k.Deposits.Remove(ctx, key)
return false, err
})
}
@ -281,7 +281,7 @@ func (keeper Keeper) RefundAndDeleteDeposits(ctx context.Context, proposalID uin
// validateInitialDeposit validates if initial deposit is greater than or equal to the minimum
// required at the time of proposal submission. This threshold amount is determined by
// the deposit parameters. Returns nil on success, error otherwise.
func (keeper Keeper) validateInitialDeposit(ctx context.Context, params v1.Params, initialDeposit sdk.Coins, proposalType v1.ProposalType) error {
func (k Keeper) validateInitialDeposit(ctx context.Context, params v1.Params, initialDeposit sdk.Coins, proposalType v1.ProposalType) error {
if !initialDeposit.IsValid() || initialDeposit.IsAnyNegative() {
return errors.Wrap(sdkerrors.ErrInvalidCoins, initialDeposit.String())
}
@ -312,7 +312,7 @@ func (keeper Keeper) validateInitialDeposit(ctx context.Context, params v1.Param
}
// validateDepositDenom validates if the deposit denom is accepted by the governance module.
func (keeper Keeper) validateDepositDenom(ctx context.Context, params v1.Params, depositAmount sdk.Coins) error {
func (k Keeper) validateDepositDenom(ctx context.Context, params v1.Params, depositAmount sdk.Coins) error {
denoms := []string{}
acceptedDenoms := make(map[string]bool, len(params.MinDeposit))
for _, coin := range params.MinDeposit {

View File

@ -2,6 +2,7 @@ package keeper
import (
"context"
stderrors "errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -17,7 +18,17 @@ import (
"github.com/cosmos/cosmos-sdk/types/query"
)
var _ v1.QueryServer = queryServer{}
var (
_ v1.QueryServer = queryServer{}
defaultVoteOptions = &v1.ProposalVoteOptions{
OptionOne: "yes",
OptionTwo: "abstain",
OptionThree: "no",
OptionFour: "no_with_veto",
OptionSpam: "spam",
}
)
type queryServer struct{ k *Keeper }
@ -53,6 +64,49 @@ func (q queryServer) Proposal(ctx context.Context, req *v1.QueryProposalRequest)
return nil, status.Error(codes.Internal, err.Error())
}
// ProposalVoteOptions returns the proposal votes options
// It returns the stringified vote options if the proposal is a multiple choice proposal
// Otherwise it returns the generic vote options
func (q queryServer) ProposalVoteOptions(ctx context.Context, req *v1.QueryProposalVoteOptionsRequest) (*v1.QueryProposalVoteOptionsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
if req.ProposalId == 0 {
return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0")
}
ok, err := q.k.Proposals.Has(ctx, req.ProposalId)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
if !ok {
return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId)
}
voteOptions, err := q.k.ProposalVoteOptions.Get(ctx, req.ProposalId)
if err != nil {
if stderrors.Is(err, collections.ErrNotFound) { // fallback to generic vote options
return &v1.QueryProposalVoteOptionsResponse{
VoteOptions: defaultVoteOptions,
}, nil
}
return nil, status.Error(codes.Internal, err.Error())
}
return &v1.QueryProposalVoteOptionsResponse{
VoteOptions: &v1.ProposalVoteOptions{
OptionOne: voteOptions.OptionOne,
OptionTwo: voteOptions.OptionTwo,
OptionThree: voteOptions.OptionThree,
OptionFour: voteOptions.OptionFour,
OptionSpam: defaultVoteOptions.OptionSpam,
},
}, nil
}
// Proposals implements the Query/Proposals gRPC method
func (q queryServer) Proposals(ctx context.Context, req *v1.QueryProposalsRequest) (*v1.QueryProposalsResponse, error) {
filteredProposals, pageRes, err := query.CollectionFilteredPaginate(ctx, q.k.Proposals, req.Pagination, func(key uint64, p v1.Proposal) (include bool, err error) {

View File

@ -68,13 +68,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposal() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
proposalRes, err := queryClient.Proposal(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotEmpty(proposalRes.Proposal.String())
suite.Require().Equal(proposalRes.Proposal.String(), expProposal.String())
@ -166,13 +168,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryProposal() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
proposalRes, err := queryClient.Proposal(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotEmpty(proposalRes.Proposal.String())
suite.Require().Equal(proposalRes.Proposal.String(), expProposal.String())
@ -373,13 +377,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposals() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
proposals, err := queryClient.Proposals(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Len(proposals.GetProposals(), len(expRes.GetProposals()))
@ -423,13 +429,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryProposals() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
proposalRes, err := queryClient.Proposals(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(proposalRes.Proposals)
suite.Require().Equal(len(proposalRes.Proposals), 1)
@ -539,13 +547,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryVote() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
vote, err := queryClient.Vote(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes, vote)
} else {
@ -654,13 +664,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryVote() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
vote, err := queryClient.Vote(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes, vote)
} else {
@ -758,13 +770,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryVotes() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
votes, err := queryClient.Votes(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetVotes(), votes.GetVotes())
} else {
@ -863,13 +877,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryVotes() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
votes, err := queryClient.Votes(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetVotes(), votes.GetVotes())
} else {
@ -945,13 +961,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryParams() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
params, err := queryClient.Params(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetDepositParams(), params.GetDepositParams()) //nolint:staticcheck // SA1019: params.MinDeposit is deprecated: Use MinInitialDeposit instead.
suite.Require().Equal(expRes.GetVotingParams(), params.GetVotingParams()) //nolint:staticcheck // SA1019: params.VotingPeriod is deprecated: Use VotingPeriod instead.
@ -1035,13 +1053,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryParams() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
params, err := queryClient.Params(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetDepositParams(), params.GetDepositParams())
suite.Require().Equal(expRes.GetVotingParams(), params.GetVotingParams())
@ -1140,13 +1160,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryDeposit() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
deposit, err := queryClient.Deposit(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(deposit.GetDeposit(), expRes.GetDeposit())
} else {
@ -1243,13 +1265,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryDeposit() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
deposit, err := queryClient.Deposit(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(deposit.GetDeposit(), expRes.GetDeposit())
} else {
@ -1339,13 +1363,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryDeposits() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
deposits, err := queryClient.Deposits(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetDeposits(), deposits.GetDeposits())
} else {
@ -1438,13 +1464,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryDeposits() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
deposits, err := queryClient.Deposits(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.GetDeposits(), deposits.GetDeposits())
} else {
@ -1580,13 +1608,15 @@ func (suite *KeeperTestSuite) TestGRPCQueryTallyResult() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
tallyRes, err := queryClient.TallyResult(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotEmpty(tallyRes.Tally.String())
suite.Require().Equal(expTally.String(), tallyRes.Tally.String())
@ -1719,13 +1749,15 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryTallyResult() {
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
if tc.malleate != nil {
tc.malleate()
}
tallyRes, err := queryClient.TallyResult(gocontext.Background(), req)
if testCase.expPass {
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotEmpty(tallyRes.Tally.String())
suite.Require().Equal(expTally.String(), tallyRes.Tally.String())
@ -1736,3 +1768,133 @@ func (suite *KeeperTestSuite) TestLegacyGRPCQueryTallyResult() {
})
}
}
func (suite *KeeperTestSuite) TestProposalVoteOptions() {
suite.reset()
testCases := []struct {
name string
malleate func()
req *v1.QueryProposalVoteOptionsRequest
expResp *v1.QueryProposalVoteOptionsResponse
errStr string
}{
{
name: "invalid proposal id",
req: &v1.QueryProposalVoteOptionsRequest{},
errStr: "proposal id can not be 0",
},
{
name: "proposal not found",
req: &v1.QueryProposalVoteOptionsRequest{ProposalId: 1},
errStr: "proposal 1 doesn't exist",
},
{
name: "non multiple choice proposal",
malleate: func() {
propTime := time.Now()
proposal := v1.Proposal{
Id: 1,
Status: v1.StatusVotingPeriod,
SubmitTime: &propTime,
VotingStartTime: &propTime,
VotingEndTime: &propTime,
Metadata: "proposal metadata",
ProposalType: v1.ProposalType_PROPOSAL_TYPE_STANDARD,
}
err := suite.govKeeper.SetProposal(suite.ctx, proposal)
suite.Require().NoError(err)
},
req: &v1.QueryProposalVoteOptionsRequest{ProposalId: 1},
expResp: &v1.QueryProposalVoteOptionsResponse{
VoteOptions: &v1.ProposalVoteOptions{
OptionOne: "yes",
OptionTwo: "abstain",
OptionThree: "no",
OptionFour: "no_with_veto",
OptionSpam: "spam",
},
},
},
{
name: "invalid multiple choice proposal",
req: &v1.QueryProposalVoteOptionsRequest{ProposalId: 2},
malleate: func() {
propTime := time.Now()
proposal := v1.Proposal{
Id: 2,
Status: v1.StatusVotingPeriod,
SubmitTime: &propTime,
VotingStartTime: &propTime,
VotingEndTime: &propTime,
Metadata: "proposal metadata",
ProposalType: v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE,
}
err := suite.govKeeper.SetProposal(suite.ctx, proposal)
suite.Require().NoError(err)
// multiple choice proposal, but no vote options set
// because the query does not check the proposal type,
// it falls back to the default vote options
},
expResp: &v1.QueryProposalVoteOptionsResponse{
VoteOptions: &v1.ProposalVoteOptions{
OptionOne: "yes",
OptionTwo: "abstain",
OptionThree: "no",
OptionFour: "no_with_veto",
OptionSpam: "spam",
},
},
},
{
name: "multiple choice proposal",
req: &v1.QueryProposalVoteOptionsRequest{ProposalId: 3},
malleate: func() {
propTime := time.Now()
proposal := v1.Proposal{
Id: 3,
Status: v1.StatusVotingPeriod,
SubmitTime: &propTime,
VotingStartTime: &propTime,
VotingEndTime: &propTime,
Metadata: "proposal metadata",
ProposalType: v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE,
}
err := suite.govKeeper.SetProposal(suite.ctx, proposal)
suite.Require().NoError(err)
err = suite.govKeeper.ProposalVoteOptions.Set(suite.ctx, proposal.Id, v1.ProposalVoteOptions{
OptionOne: "Vote for @tac0turle",
OptionTwo: "Vote for @facudomedica",
OptionThree: "Vote for @alexanderbez",
})
suite.Require().NoError(err)
},
expResp: &v1.QueryProposalVoteOptionsResponse{
VoteOptions: &v1.ProposalVoteOptions{
OptionOne: "Vote for @tac0turle",
OptionTwo: "Vote for @facudomedica",
OptionThree: "Vote for @alexanderbez",
OptionSpam: "spam",
},
},
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
if tc.malleate != nil {
tc.malleate()
}
resp, err := suite.queryClient.ProposalVoteOptions(suite.ctx, tc.req)
if tc.errStr != "" {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.errStr)
} else {
suite.Require().NoError(err)
suite.Require().Equal(tc.expResp, resp)
}
})
}
}

View File

@ -48,16 +48,22 @@ type Keeper struct {
// should be the x/gov module account.
authority string
Schema collections.Schema
Schema collections.Schema
// Constitution value: constitution
Constitution collections.Item[string]
Params collections.Item[v1.Params]
// Params stores the governance parameters
Params collections.Item[v1.Params]
// Deposits key: proposalID+depositorAddr | value: Deposit
Deposits collections.Map[collections.Pair[uint64, sdk.AccAddress], v1.Deposit]
// Votes key: proposalID+voterAddr | value: Vote
Votes collections.Map[collections.Pair[uint64, sdk.AccAddress], v1.Vote]
Votes collections.Map[collections.Pair[uint64, sdk.AccAddress], v1.Vote]
// ProposalID is a counter for proposals. It tracks the next proposal ID to be issued.
ProposalID collections.Sequence
// Proposals key:proposalID | value: Proposal
Proposals collections.Map[uint64, v1.Proposal]
// ProposalVoteOptions key: proposalID | value:
// This is used to store multiple choice vote options
ProposalVoteOptions collections.Map[uint64, v1.ProposalVoteOptions]
// ActiveProposalsQueue key: votingEndTime+proposalID | value: proposalID
ActiveProposalsQueue collections.Map[collections.Pair[time.Time, uint64], uint64] // TODO(tip): this should be simplified and go into an index.
// InactiveProposalsQueue key: depositEndTime+proposalID | value: proposalID
@ -123,6 +129,7 @@ func NewKeeper(
Votes: collections.NewMap(sb, types.VotesKeyPrefix, "votes", collections.PairKeyCodec(collections.Uint64Key, sdk.LengthPrefixedAddressKey(sdk.AccAddressKey)), codec.CollValue[v1.Vote](cdc)), //nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
ProposalID: collections.NewSequence(sb, types.ProposalIDKey, "proposal_id"),
Proposals: collections.NewMap(sb, types.ProposalsKeyPrefix, "proposals", collections.Uint64Key, codec.CollValue[v1.Proposal](cdc)),
ProposalVoteOptions: collections.NewMap(sb, types.ProposalVoteOptionsKeyPrefix, "proposal_vote_options", collections.Uint64Key, codec.CollValue[v1.ProposalVoteOptions](cdc)),
ActiveProposalsQueue: collections.NewMap(sb, types.ActiveProposalQueuePrefix, "active_proposals_queue", collections.PairKeyCodec(sdk.TimeKey, collections.Uint64Key), collections.Uint64Value), // sdk.TimeKey is needed to retain state compatibility
InactiveProposalsQueue: collections.NewMap(sb, types.InactiveProposalQueuePrefix, "inactive_proposals_queue", collections.PairKeyCodec(sdk.TimeKey, collections.Uint64Key), collections.Uint64Value), // sdk.TimeKey is needed to retain state compatibility
VotingPeriodProposals: collections.NewMap(sb, types.VotingPeriodProposalKeyPrefix, "voting_period_proposals", collections.Uint64Key, collections.BytesValue),
@ -135,7 +142,7 @@ func NewKeeper(
return k
}
// Hooks gets the hooks for governance *Keeper {
// Hooks gets the hooks for governance Keeper
func (k *Keeper) Hooks() types.GovHooks {
if k.hooks == nil {
// return a no-op implementation if no hooks are set

View File

@ -49,7 +49,7 @@ func (suite *KeeperTestSuite) reset() {
// Populate the gov account with some coins, as the TestProposal we have
// is a MsgSend from the gov account.
coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100000)))
coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(1000000)))
err := bankKeeper.MintCoins(suite.ctx, mintModuleName, coins)
suite.NoError(err)
err = bankKeeper.SendCoinsFromModuleToModule(ctx, mintModuleName, types.ModuleName, coins)

View File

@ -118,6 +118,45 @@ func (k msgServer) SubmitProposal(goCtx context.Context, msg *v1.MsgSubmitPropos
}, nil
}
// SubmitMultipleChoiceProposal implements the MsgServer.SubmitMultipleChoiceProposal method.
func (k msgServer) SubmitMultipleChoiceProposal(ctx context.Context, msg *v1.MsgSubmitMultipleChoiceProposal) (*v1.MsgSubmitMultipleChoiceProposalResponse, error) {
resp, err := k.SubmitProposal(ctx, &v1.MsgSubmitProposal{
InitialDeposit: msg.InitialDeposit,
Proposer: msg.Proposer,
Title: msg.Title,
Summary: msg.Summary,
Metadata: msg.Metadata,
ProposalType: v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE,
})
if err != nil {
return nil, err
}
if msg.VoteOptions == nil {
return nil, sdkerrors.ErrInvalidRequest.Wrap("vote options cannot be nil")
}
// check that if a vote option is provided, the previous one is also provided
if (msg.VoteOptions.OptionTwo != "" && msg.VoteOptions.OptionOne == "") ||
(msg.VoteOptions.OptionThree != "" && msg.VoteOptions.OptionTwo == "") ||
(msg.VoteOptions.OptionFour != "" && msg.VoteOptions.OptionThree == "") {
return nil, sdkerrors.ErrInvalidRequest.Wrap("if a vote option is provided, the previous one must also be provided")
}
// check that at least two vote options are provided
if msg.VoteOptions.OptionOne == "" && msg.VoteOptions.OptionTwo == "" {
return nil, sdkerrors.ErrInvalidRequest.Wrap("vote options cannot be empty, two or more options must be provided")
}
if err := k.ProposalVoteOptions.Set(ctx, resp.ProposalId, *msg.VoteOptions); err != nil {
return nil, err
}
return &v1.MsgSubmitMultipleChoiceProposalResponse{
ProposalId: resp.ProposalId,
}, nil
}
// CancelProposal implements the MsgServer.CancelProposal method.
func (k msgServer) CancelProposal(goCtx context.Context, msg *v1.MsgCancelProposal) (*v1.MsgCancelProposalResponse, error) {
_, err := k.authKeeper.AddressCodec().StringToBytes(msg.Proposer)

View File

@ -298,6 +298,83 @@ func (suite *KeeperTestSuite) TestMsgSubmitProposal() {
}
}
// TestSubmitMultipleChoiceProposal tests only multiple choice proposal specific logic.
// Internally the message uses MsgSubmitProposal, which is tested above.
func (suite *KeeperTestSuite) TestSubmitMultipleChoiceProposal() {
suite.reset()
addrs := suite.addrs
proposer := addrs[0]
initialDeposit := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100000)))
cases := map[string]struct {
preRun func() (*v1.MsgSubmitMultipleChoiceProposal, error)
expErr bool
expErrMsg string
}{
"empty options": {
preRun: func() (*v1.MsgSubmitMultipleChoiceProposal, error) {
return v1.NewMultipleChoiceMsgSubmitProposal(
initialDeposit,
proposer.String(),
"mandatory metadata",
"Proposal",
"description of proposal",
&v1.ProposalVoteOptions{},
)
},
expErr: true,
expErrMsg: "vote options cannot be empty, two or more options must be provided",
},
"invalid options": {
preRun: func() (*v1.MsgSubmitMultipleChoiceProposal, error) {
return v1.NewMultipleChoiceMsgSubmitProposal(
initialDeposit,
proposer.String(),
"mandatory metadata",
"Proposal",
"description of proposal",
&v1.ProposalVoteOptions{
OptionOne: "Vote for me",
OptionFour: "Vote for them",
},
)
},
expErr: true,
expErrMsg: "if a vote option is provided, the previous one must also be provided",
},
"valid proposal": {
preRun: func() (*v1.MsgSubmitMultipleChoiceProposal, error) {
return v1.NewMultipleChoiceMsgSubmitProposal(
initialDeposit,
proposer.String(),
"mandatory metadata",
"Proposal",
"description of proposal",
&v1.ProposalVoteOptions{
OptionOne: "Vote for me",
OptionTwo: "Vote for them",
},
)
},
},
}
for name, tc := range cases {
suite.Run(name, func() {
msg, err := tc.preRun()
suite.Require().NoError(err)
res, err := suite.msgSrvr.SubmitMultipleChoiceProposal(suite.ctx, msg)
if tc.expErr {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.expErrMsg)
} else {
suite.Require().NoError(err)
suite.Require().NotNil(res.ProposalId)
}
})
}
}
func (suite *KeeperTestSuite) TestMsgCancelProposal() {
govAcct := suite.govKeeper.GetGovernanceAccount(suite.ctx).GetAddress()
addrs := suite.addrs

View File

@ -19,19 +19,23 @@ import (
)
// SubmitProposal creates a new proposal given an array of messages
func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress, proposalType v1.ProposalType) (v1.Proposal, error) {
params, err := keeper.Params.Get(ctx)
func (k Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress, proposalType v1.ProposalType) (v1.Proposal, error) {
params, err := k.Params.Get(ctx)
if err != nil {
return v1.Proposal{}, err
}
// additional checks per proposal types
if proposalType == v1.ProposalType_PROPOSAL_TYPE_OPTIMISTIC {
proposerStr, _ := keeper.authKeeper.AddressCodec().BytesToString(proposer)
switch proposalType {
case v1.ProposalType_PROPOSAL_TYPE_OPTIMISTIC:
proposerStr, _ := k.authKeeper.AddressCodec().BytesToString(proposer)
if len(params.OptimisticAuthorizedAddresses) > 0 && !slices.Contains(params.OptimisticAuthorizedAddresses, proposerStr) {
return v1.Proposal{}, errorsmod.Wrap(types.ErrInvalidProposer, "proposer is not authorized to submit optimistic proposal")
}
case v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE:
if len(messages) > 0 { // cannot happen, except when the proposal is created via keeper call instead of message server.
return v1.Proposal{}, errorsmod.Wrap(types.ErrInvalidProposalMsg, "multiple choice proposal should not contain any messages")
}
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
@ -48,7 +52,7 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
}
}
signers, _, err := keeper.cdc.GetMsgV1Signers(msg)
signers, _, err := k.cdc.GetMsgV1Signers(msg)
if err != nil {
return v1.Proposal{}, err
}
@ -57,12 +61,12 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
}
// assert that the governance module account is the only signer of the messages
if !bytes.Equal(signers[0], keeper.GetGovernanceAccount(ctx).GetAddress()) {
if !bytes.Equal(signers[0], k.GetGovernanceAccount(ctx).GetAddress()) {
return v1.Proposal{}, errorsmod.Wrapf(types.ErrInvalidSigner, sdk.AccAddress(signers[0]).String())
}
// use the msg service router to see that there is a valid route for that message.
handler := keeper.router.Handler(msg)
handler := k.router.Handler(msg)
if handler == nil {
return v1.Proposal{}, errorsmod.Wrap(types.ErrUnroutableProposalMsg, sdk.MsgTypeURL(msg))
}
@ -86,7 +90,7 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
}
proposalID, err := keeper.ProposalID.Next(ctx)
proposalID, err := k.ProposalID.Next(ctx)
if err != nil {
return v1.Proposal{}, err
}
@ -97,17 +101,17 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
return v1.Proposal{}, err
}
err = keeper.SetProposal(ctx, proposal)
err = k.SetProposal(ctx, proposal)
if err != nil {
return v1.Proposal{}, err
}
err = keeper.InactiveProposalsQueue.Set(ctx, collections.Join(*proposal.DepositEndTime, proposalID), proposalID)
err = k.InactiveProposalsQueue.Set(ctx, collections.Join(*proposal.DepositEndTime, proposalID), proposalID)
if err != nil {
return v1.Proposal{}, err
}
// called right after a proposal is submitted
err = keeper.Hooks().AfterProposalSubmission(ctx, proposalID)
err = k.Hooks().AfterProposalSubmission(ctx, proposalID)
if err != nil {
return v1.Proposal{}, err
}
@ -124,9 +128,9 @@ func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, met
}
// CancelProposal will cancel proposal before the voting period ends
func (keeper Keeper) CancelProposal(ctx context.Context, proposalID uint64, proposer string) error {
func (k Keeper) CancelProposal(ctx context.Context, proposalID uint64, proposer string) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
proposal, err := keeper.Proposals.Get(ctx, proposalID)
proposal, err := k.Proposals.Get(ctx, proposalID)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return types.ErrInvalidProposal.Wrapf("proposal %d doesn't exist", proposalID)
@ -134,7 +138,7 @@ func (keeper Keeper) CancelProposal(ctx context.Context, proposalID uint64, prop
return err
}
params, err := keeper.Params.Get(ctx)
params, err := k.Params.Get(ctx)
if err != nil {
return err
}
@ -171,24 +175,24 @@ func (keeper Keeper) CancelProposal(ctx context.Context, proposalID uint64, prop
// burn the (deposits * proposal_cancel_rate) amount or sent to cancellation destination address.
// and deposits * (1 - proposal_cancel_rate) will be sent to depositors.
err = keeper.ChargeDeposit(ctx, proposal.Id, params.ProposalCancelDest, params.ProposalCancelRatio)
err = k.ChargeDeposit(ctx, proposal.Id, params.ProposalCancelDest, params.ProposalCancelRatio)
if err != nil {
return err
}
if proposal.VotingStartTime != nil {
err = keeper.deleteVotes(ctx, proposal.Id)
err = k.deleteVotes(ctx, proposal.Id)
if err != nil {
return err
}
}
err = keeper.DeleteProposal(ctx, proposal.Id)
err = k.DeleteProposal(ctx, proposal.Id)
if err != nil {
return err
}
keeper.Logger(ctx).Info(
k.Logger(ctx).Info(
"proposal is canceled by proposer",
"proposal", proposal.Id,
"proposer", proposal.Proposer,
@ -198,57 +202,57 @@ func (keeper Keeper) CancelProposal(ctx context.Context, proposalID uint64, prop
}
// SetProposal sets a proposal to store.
func (keeper Keeper) SetProposal(ctx context.Context, proposal v1.Proposal) error {
func (k Keeper) SetProposal(ctx context.Context, proposal v1.Proposal) error {
if proposal.Status == v1.StatusVotingPeriod {
err := keeper.VotingPeriodProposals.Set(ctx, proposal.Id, []byte{1})
err := k.VotingPeriodProposals.Set(ctx, proposal.Id, []byte{1})
if err != nil {
return err
}
} else {
err := keeper.VotingPeriodProposals.Remove(ctx, proposal.Id)
err := k.VotingPeriodProposals.Remove(ctx, proposal.Id)
if err != nil {
return err
}
}
return keeper.Proposals.Set(ctx, proposal.Id, proposal)
return k.Proposals.Set(ctx, proposal.Id, proposal)
}
// DeleteProposal deletes a proposal from store.
func (keeper Keeper) DeleteProposal(ctx context.Context, proposalID uint64) error {
proposal, err := keeper.Proposals.Get(ctx, proposalID)
func (k Keeper) DeleteProposal(ctx context.Context, proposalID uint64) error {
proposal, err := k.Proposals.Get(ctx, proposalID)
if err != nil {
return err
}
if proposal.DepositEndTime != nil {
err := keeper.InactiveProposalsQueue.Remove(ctx, collections.Join(*proposal.DepositEndTime, proposalID))
err := k.InactiveProposalsQueue.Remove(ctx, collections.Join(*proposal.DepositEndTime, proposalID))
if err != nil {
return err
}
}
if proposal.VotingEndTime != nil {
err := keeper.ActiveProposalsQueue.Remove(ctx, collections.Join(*proposal.VotingEndTime, proposalID))
err := k.ActiveProposalsQueue.Remove(ctx, collections.Join(*proposal.VotingEndTime, proposalID))
if err != nil {
return err
}
err = keeper.VotingPeriodProposals.Remove(ctx, proposalID)
err = k.VotingPeriodProposals.Remove(ctx, proposalID)
if err != nil {
return err
}
}
return keeper.Proposals.Remove(ctx, proposalID)
return k.Proposals.Remove(ctx, proposalID)
}
// ActivateVotingPeriod activates the voting period of a proposal
func (keeper Keeper) ActivateVotingPeriod(ctx context.Context, proposal v1.Proposal) error {
func (k Keeper) ActivateVotingPeriod(ctx context.Context, proposal v1.Proposal) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
startTime := sdkCtx.HeaderInfo().Time
proposal.VotingStartTime = &startTime
var votingPeriod *time.Duration
params, err := keeper.Params.Get(ctx)
params, err := k.Params.Get(ctx)
if err != nil {
return err
}
@ -261,15 +265,15 @@ func (keeper Keeper) ActivateVotingPeriod(ctx context.Context, proposal v1.Propo
endTime := proposal.VotingStartTime.Add(*votingPeriod)
proposal.VotingEndTime = &endTime
proposal.Status = v1.StatusVotingPeriod
err = keeper.SetProposal(ctx, proposal)
err = k.SetProposal(ctx, proposal)
if err != nil {
return err
}
err = keeper.InactiveProposalsQueue.Remove(ctx, collections.Join(*proposal.DepositEndTime, proposal.Id))
err = k.InactiveProposalsQueue.Remove(ctx, collections.Join(*proposal.DepositEndTime, proposal.Id))
if err != nil {
return err
}
return keeper.ActiveProposalsQueue.Set(ctx, collections.Join(*proposal.VotingEndTime, proposal.Id), proposal.Id)
return k.ActiveProposalsQueue.Set(ctx, collections.Join(*proposal.VotingEndTime, proposal.Id), proposal.Id)
}

View File

@ -167,6 +167,7 @@ func (suite *KeeperTestSuite) TestSubmitProposal() {
}{
{&tp, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_STANDARD, nil},
{&tp, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_EXPEDITED, nil},
{nil, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE, nil},
// Keeper does not check the validity of title and description, no error
{&v1beta1.TextProposal{Title: "", Description: "description"}, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_STANDARD, nil},
{&v1beta1.TextProposal{Title: strings.Repeat("1234567890", 100), Description: "description"}, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_STANDARD, nil},
@ -176,12 +177,19 @@ func (suite *KeeperTestSuite) TestSubmitProposal() {
{&tp, randomAddr.String(), "", v1.ProposalType_PROPOSAL_TYPE_STANDARD, types.ErrInvalidSigner},
// error only when invalid route
{&invalidProposalRoute{}, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_STANDARD, types.ErrNoProposalHandlerExists},
// error invalid multiple choice proposal
{&tp, govAcct, "", v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE, types.ErrInvalidProposalMsg},
}
for i, tc := range testCases {
prop, err := v1.NewLegacyContent(tc.content, tc.authority)
suite.Require().NoError(err)
_, err = suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{prop}, tc.metadata, "title", "", suite.addrs[0], tc.proposalType)
msg := []sdk.Msg{}
if tc.content != nil {
prop, err := v1.NewLegacyContent(tc.content, tc.authority)
suite.Require().NoError(err)
msg = append(msg, prop)
}
_, err := suite.govKeeper.SubmitProposal(suite.ctx, msg, tc.metadata, "title", "", suite.addrs[0], tc.proposalType)
suite.Require().True(errors.Is(tc.expectedErr, err), "tc #%d; got: %v, expected: %v", i, err, tc.expectedErr)
}
}

View File

@ -11,25 +11,25 @@ import (
)
// Tally iterates over the votes and updates the tally of a proposal based on the voting power of the voters
func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
validators, err := keeper.getCurrentValidators(ctx)
func (k Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
validators, err := k.getCurrentValidators(ctx)
if err != nil {
return false, false, v1.TallyResult{}, err
}
totalVoterPower, results, err := keeper.calculateVoteResultsAndVotingPower(ctx, proposal.Id, validators)
totalVoterPower, results, err := k.calculateVoteResultsAndVotingPower(ctx, proposal.Id, validators)
if err != nil {
return false, false, v1.TallyResult{}, err
}
params, err := keeper.Params.Get(ctx)
params, err := k.Params.Get(ctx)
if err != nil {
return false, false, v1.TallyResult{}, err
}
tallyResults = v1.NewTallyResultFromMap(results)
// If there is no staked coins, the proposal fails
totalBonded, err := keeper.sk.TotalBondedTokens(ctx)
totalBonded, err := k.sk.TotalBondedTokens(ctx)
if err != nil {
return false, false, v1.TallyResult{}, err
}
@ -47,18 +47,24 @@ func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, b
switch proposal.ProposalType {
case v1.ProposalType_PROPOSAL_TYPE_OPTIMISTIC:
return keeper.tallyOptimistic(totalVoterPower, totalBonded, results, params)
return k.tallyOptimistic(totalVoterPower, totalBonded, results, params)
case v1.ProposalType_PROPOSAL_TYPE_EXPEDITED:
return keeper.tallyExpedited(totalVoterPower, totalBonded, results, params)
return k.tallyExpedited(totalVoterPower, totalBonded, results, params)
case v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE:
return keeper.tallyMultipleChoice(totalVoterPower, totalBonded, results, params) // TODO(@julienrbrt): implement in follow up
return k.tallyMultipleChoice(totalVoterPower, totalBonded, results, params)
default:
return keeper.tallyStandard(totalVoterPower, totalBonded, results, params)
return k.tallyStandard(totalVoterPower, totalBonded, results, params)
}
}
// tallyStandard tallies the votes of a standard proposal
func (keeper Keeper) tallyStandard(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
// If there is not enough quorum of votes, the proposal fails
// If no one votes (everyone abstains), proposal fails
// If more than 1/3 of voters veto, proposal fails
// If more than 1/2 of non-abstaining voters vote Yes, proposal passes
// If more than 1/2 of non-abstaining voters vote No, proposal fails
// Checking for spam votes is done before calling this function
func (k Keeper) tallyStandard(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
tallyResults = v1.NewTallyResultFromMap(results)
// If there is not enough quorum of votes, the proposal fails
@ -91,7 +97,13 @@ func (keeper Keeper) tallyStandard(totalVoterPower math.LegacyDec, totalBonded m
}
// tallyExpedited tallies the votes of an expedited proposal
func (keeper Keeper) tallyExpedited(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
// If there is not enough quorum of votes, the proposal fails
// If no one votes (everyone abstains), proposal fails
// If more than 1/3 of voters veto, proposal fails
// If more than 2/3 of non-abstaining voters vote Yes, proposal passes
// If more than 1/2 of non-abstaining voters vote No, proposal fails
// Checking for spam votes is done before calling this function
func (k Keeper) tallyExpedited(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
tallyResults = v1.NewTallyResultFromMap(results)
// If there is not enough quorum of votes, the proposal fails
@ -124,7 +136,11 @@ func (keeper Keeper) tallyExpedited(totalVoterPower math.LegacyDec, totalBonded
}
// tallyOptimistic tallies the votes of an optimistic proposal
func (keeper Keeper) tallyOptimistic(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
// If proposal has no votes, proposal passes
// If the threshold of no is reached, proposal fails
// Any other case, proposal passes
// Checking for spam votes is done before calling this function
func (k Keeper) tallyOptimistic(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
tallyResults = v1.NewTallyResultFromMap(results)
optimisticNoThreshold, _ := math.LegacyNewDecFromStr(params.OptimisticRejectedThreshold)
@ -142,7 +158,10 @@ func (keeper Keeper) tallyOptimistic(totalVoterPower math.LegacyDec, totalBonded
}
// tallyMultipleChoice tallies the votes of a multiple choice proposal
func (keeper Keeper) tallyMultipleChoice(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
// If there is not enough quorum of votes, the proposal fails
// Any other case, proposal passes
// Checking for spam votes is done before calling this function
func (k Keeper) tallyMultipleChoice(totalVoterPower math.LegacyDec, totalBonded math.Int, results map[v1.VoteOption]math.LegacyDec, params v1.Params) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) {
tallyResults = v1.NewTallyResultFromMap(results)
// If there is not enough quorum of votes, the proposal fails
@ -152,14 +171,16 @@ func (keeper Keeper) tallyMultipleChoice(totalVoterPower math.LegacyDec, totalBo
return false, params.BurnVoteQuorum, tallyResults, nil
}
// a multiple choice proposal always passes unless it was spam or quorum was not reached.
return true, false, tallyResults, nil
}
// getCurrentValidators fetches all the bonded validators, insert them into currValidators
func (keeper Keeper) getCurrentValidators(ctx context.Context) (map[string]v1.ValidatorGovInfo, error) {
func (k Keeper) getCurrentValidators(ctx context.Context) (map[string]v1.ValidatorGovInfo, error) {
currValidators := make(map[string]v1.ValidatorGovInfo)
if err := keeper.sk.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.ValidatorI) (stop bool) {
valBz, err := keeper.sk.ValidatorAddressCodec().StringToBytes(validator.GetOperator())
if err := k.sk.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.ValidatorI) (stop bool) {
valBz, err := k.sk.ValidatorAddressCodec().StringToBytes(validator.GetOperator())
if err != nil {
return false
}
@ -181,7 +202,7 @@ func (keeper Keeper) getCurrentValidators(ctx context.Context) (map[string]v1.Va
// calculateVoteResultsAndVotingPower iterate over all votes, tally up the voting power of each validator
// and returns the votes results from voters
func (keeper Keeper) calculateVoteResultsAndVotingPower(
func (k Keeper) calculateVoteResultsAndVotingPower(
ctx context.Context,
proposalID uint64,
validators map[string]v1.ValidatorGovInfo,
@ -191,14 +212,14 @@ func (keeper Keeper) calculateVoteResultsAndVotingPower(
// iterate over all votes, tally up the voting power of each validator
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposalID)
if err := keeper.Votes.Walk(ctx, rng, func(key collections.Pair[uint64, sdk.AccAddress], vote v1.Vote) (bool, error) {
if err := k.Votes.Walk(ctx, rng, func(key collections.Pair[uint64, sdk.AccAddress], vote v1.Vote) (bool, error) {
// if validator, just record it in the map
voter, err := keeper.authKeeper.AddressCodec().StringToBytes(vote.Voter)
voter, err := k.authKeeper.AddressCodec().StringToBytes(vote.Voter)
if err != nil {
return false, err
}
valAddrStr, err := keeper.sk.ValidatorAddressCodec().BytesToString(voter)
valAddrStr, err := k.sk.ValidatorAddressCodec().BytesToString(voter)
if err != nil {
return false, err
}
@ -209,7 +230,7 @@ func (keeper Keeper) calculateVoteResultsAndVotingPower(
}
// iterate over all delegations from voter, deduct from any delegated-to validators
err = keeper.sk.IterateDelegations(ctx, voter, func(index int64, delegation sdk.DelegationI) (stop bool) {
err = k.sk.IterateDelegations(ctx, voter, func(index int64, delegation sdk.DelegationI) (stop bool) {
valAddrStr := delegation.GetValidatorAddr()
if val, ok := validators[valAddrStr]; ok {
@ -236,7 +257,7 @@ func (keeper Keeper) calculateVoteResultsAndVotingPower(
return false, err
}
return false, keeper.Votes.Remove(ctx, collections.Join(vote.ProposalId, sdk.AccAddress(voter)))
return false, k.Votes.Remove(ctx, collections.Join(vote.ProposalId, sdk.AccAddress(voter)))
}); err != nil {
return math.LegacyDec{}, nil, err
}

View File

@ -939,3 +939,329 @@ func TestTally_Optimistic(t *testing.T) {
})
}
}
// TODO(@julienrbrt): refactor tally result to fit all proposal types
func TestTally_MultipleChoice(t *testing.T) {
tests := []struct {
name string
setup func(tallyFixture)
expectedPass bool
expectedBurn bool
expectedTally v1.TallyResult
expectedError string
}{
{
name: "no votes, no bonded tokens: prop fails",
setup: func(s tallyFixture) {
setTotalBonded(s, 0)
},
expectedPass: false,
expectedBurn: false,
expectedTally: v1.TallyResult{
YesCount: "0",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "no votes: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "0",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "one validator votes: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_THREE)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "0",
AbstainCount: "0",
NoCount: "1000000",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "one account votes without delegation: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
delegatorVote(s, s.delAddrs[0], nil, v1.VoteOption_VOTE_OPTION_ONE)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "0",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "one delegator votes: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
delegations := []stakingtypes.Delegation{{
DelegatorAddress: s.delAddrs[0].String(),
ValidatorAddress: s.valAddrs[0].String(),
Shares: sdkmath.LegacyNewDec(42),
}}
delegatorVote(s, s.delAddrs[0], delegations, v1.VoteOption_VOTE_OPTION_ONE)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "42",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "one delegator votes yes, validator votes also yes: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
delegations := []stakingtypes.Delegation{{
DelegatorAddress: s.delAddrs[0].String(),
ValidatorAddress: s.valAddrs[0].String(),
Shares: sdkmath.LegacyNewDec(42),
}}
delegatorVote(s, s.delAddrs[0], delegations, v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_ONE)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "1000000",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "one delegator votes yes, validator votes no: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
delegations := []stakingtypes.Delegation{{
DelegatorAddress: s.delAddrs[0].String(),
ValidatorAddress: s.valAddrs[0].String(),
Shares: sdkmath.LegacyNewDec(42),
}}
delegatorVote(s, s.delAddrs[0], delegations, v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_THREE)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "42",
AbstainCount: "0",
NoCount: "999958",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
// one delegator delegates 42 shares to 2 different validators (21 each)
// delegator votes yes
// first validator votes yes
// second validator votes no
// third validator (no delegation) votes abstain
name: "delegator with mixed delegations: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
delegations := []stakingtypes.Delegation{
{
DelegatorAddress: s.delAddrs[0].String(),
ValidatorAddress: s.valAddrs[0].String(),
Shares: sdkmath.LegacyNewDec(21),
},
{
DelegatorAddress: s.delAddrs[0].String(),
ValidatorAddress: s.valAddrs[1].String(),
Shares: sdkmath.LegacyNewDec(21),
},
}
delegatorVote(s, s.delAddrs[0], delegations, v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_THREE)
validatorVote(s, s.valAddrs[1], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[2], v1.VoteOption_VOTE_OPTION_TWO)
},
expectedPass: false,
expectedBurn: true, // burn because quorum not reached
expectedTally: v1.TallyResult{
YesCount: "1000021",
AbstainCount: "1000000",
NoCount: "999979",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "quorum reached with only abstain: always passes in multiple choice tally",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_TWO)
validatorVote(s, s.valAddrs[1], v1.VoteOption_VOTE_OPTION_TWO)
validatorVote(s, s.valAddrs[2], v1.VoteOption_VOTE_OPTION_TWO)
validatorVote(s, s.valAddrs[3], v1.VoteOption_VOTE_OPTION_TWO)
},
expectedPass: true,
expectedBurn: false,
expectedTally: v1.TallyResult{
YesCount: "0",
AbstainCount: "4000000",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "quorum reached with a majority of option 4: always passes in multiple choice tally",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[1], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[2], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[3], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[4], v1.VoteOption_VOTE_OPTION_FOUR)
validatorVote(s, s.valAddrs[5], v1.VoteOption_VOTE_OPTION_FOUR)
validatorVote(s, s.valAddrs[6], v1.VoteOption_VOTE_OPTION_FOUR)
},
expectedPass: true,
expectedBurn: false,
expectedTally: v1.TallyResult{
YesCount: "4000000",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "3000000",
SpamCount: "0",
},
},
{
name: "quorum reached, equality: always passes in multiple choice tally",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[1], v1.VoteOption_VOTE_OPTION_ONE)
validatorVote(s, s.valAddrs[2], v1.VoteOption_VOTE_OPTION_THREE)
validatorVote(s, s.valAddrs[3], v1.VoteOption_VOTE_OPTION_THREE)
},
expectedPass: true,
expectedBurn: false,
expectedTally: v1.TallyResult{
YesCount: "2000000",
AbstainCount: "0",
NoCount: "2000000",
NoWithVetoCount: "0",
SpamCount: "0",
},
},
{
name: "quorum reached with spam > all other votes: prop fails/burn deposit",
setup: func(s tallyFixture) {
setTotalBonded(s, 10000000)
validatorVote(s, s.valAddrs[0], v1.VoteOption_VOTE_OPTION_ONE)
// spam votes
validatorVote(s, s.valAddrs[1], v1.VoteOption_VOTE_OPTION_SPAM)
validatorVote(s, s.valAddrs[2], v1.VoteOption_VOTE_OPTION_SPAM)
validatorVote(s, s.valAddrs[3], v1.VoteOption_VOTE_OPTION_SPAM)
validatorVote(s, s.valAddrs[4], v1.VoteOption_VOTE_OPTION_SPAM)
validatorVote(s, s.valAddrs[5], v1.VoteOption_VOTE_OPTION_SPAM)
validatorVote(s, s.valAddrs[6], v1.VoteOption_VOTE_OPTION_SPAM)
},
expectedPass: false,
expectedBurn: true,
expectedTally: v1.TallyResult{
YesCount: "1000000",
AbstainCount: "0",
NoCount: "0",
NoWithVetoCount: "0",
SpamCount: "6000000",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
govKeeper, mocks, _, ctx := setupGovKeeper(t, mockAccountKeeperExpectations)
params := v1.DefaultParams()
// Ensure params value are different than false
params.BurnVoteQuorum = true
params.BurnVoteVeto = true
err := govKeeper.Params.Set(ctx, params)
require.NoError(t, err)
var (
numVals = 10
numDelegators = 5
addrs = simtestutil.CreateRandomAccounts(numVals + numDelegators)
valAddrs = simtestutil.ConvertAddrsToValAddrs(addrs[:numVals])
delAddrs = addrs[numVals:]
)
// Mocks a bunch of validators
mocks.stakingKeeper.EXPECT().
IterateBondedValidatorsByPower(ctx, gomock.Any()).
DoAndReturn(
func(ctx context.Context, fn func(index int64, validator sdk.ValidatorI) bool) error {
for i := int64(0); i < int64(numVals); i++ {
fn(i, stakingtypes.Validator{
OperatorAddress: valAddrs[i].String(),
Status: stakingtypes.Bonded,
Tokens: sdkmath.NewInt(1000000),
DelegatorShares: sdkmath.LegacyNewDec(1000000),
})
}
return nil
})
// Submit and activate a proposal
proposal, err := govKeeper.SubmitProposal(ctx, nil, "", "title", "summary", delAddrs[0], v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE)
require.NoError(t, err)
err = govKeeper.ProposalVoteOptions.Set(ctx, proposal.Id, v1.ProposalVoteOptions{
OptionOne: "Vote Option 1",
OptionTwo: "Vote Option 2",
OptionThree: "Vote Option 3",
OptionFour: "Vote Option 4",
})
require.NoError(t, err)
err = govKeeper.ActivateVotingPeriod(ctx, proposal)
require.NoError(t, err)
suite := tallyFixture{
t: t,
proposal: proposal,
valAddrs: valAddrs,
delAddrs: delAddrs,
ctx: ctx,
keeper: govKeeper,
mocks: mocks,
}
tt.setup(suite)
pass, burn, tally, err := govKeeper.Tally(ctx, proposal)
require.NoError(t, err)
assert.Equal(t, tt.expectedPass, pass, "wrong pass")
assert.Equal(t, tt.expectedBurn, burn, "wrong burn")
assert.Equal(t, tt.expectedTally, tally)
// Assert votes removal after tally
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposal.Id)
_, err = suite.keeper.Votes.Iterate(suite.ctx, rng)
assert.NoError(t, err)
})
}
}

View File

@ -2,6 +2,7 @@ package keeper
import (
"context"
stderrors "errors"
"fmt"
"cosmossdk.io/collections"
@ -13,9 +14,9 @@ import (
)
// AddVote adds a vote on a specific proposal
func (keeper Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress, options v1.WeightedVoteOptions, metadata string) error {
func (k Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress, options v1.WeightedVoteOptions, metadata string) error {
// Check if proposal is in voting period.
inVotingPeriod, err := keeper.VotingPeriodProposals.Has(ctx, proposalID)
inVotingPeriod, err := k.VotingPeriodProposals.Has(ctx, proposalID)
if err != nil {
return err
}
@ -24,12 +25,12 @@ func (keeper Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr s
return errors.Wrapf(types.ErrInactiveProposal, "%d", proposalID)
}
if err := keeper.assertMetadataLength(metadata); err != nil {
if err := k.assertMetadataLength(metadata); err != nil {
return err
}
// get proposal
proposal, err := keeper.Proposals.Get(ctx, proposalID)
proposal, err := k.Proposals.Get(ctx, proposalID)
if err != nil {
return err
}
@ -40,21 +41,41 @@ func (keeper Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr s
if option.Option != v1.OptionNo && option.Option != v1.OptionSpam {
return errors.Wrap(types.ErrInvalidVote, "optimistic proposals can only be rejected")
}
default:
if !v1.ValidWeightedVoteOption(*option) {
return errors.Wrap(types.ErrInvalidVote, option.String())
case v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE:
proposalOptionsStr, err := k.ProposalVoteOptions.Get(ctx, proposalID)
if err != nil {
if stderrors.Is(err, collections.ErrNotFound) {
return errors.Wrap(types.ErrInvalidProposal, "invalid multiple choice proposal, no options set")
}
return err
}
// verify votes only on existing votes
if proposalOptionsStr.OptionOne == "" && option.Option == v1.OptionOne { // should never trigger option one is always mandatory
return errors.Wrap(types.ErrInvalidVote, "invalid vote option")
} else if proposalOptionsStr.OptionTwo == "" && option.Option == v1.OptionTwo { // should never trigger option two is always mandatory
return errors.Wrap(types.ErrInvalidVote, "invalid vote option")
} else if proposalOptionsStr.OptionThree == "" && option.Option == v1.OptionThree {
return errors.Wrap(types.ErrInvalidVote, "invalid vote option")
} else if proposalOptionsStr.OptionFour == "" && option.Option == v1.OptionFour {
return errors.Wrap(types.ErrInvalidVote, "invalid vote option")
}
}
if !v1.ValidWeightedVoteOption(*option) {
return errors.Wrap(types.ErrInvalidVote, option.String())
}
}
vote := v1.NewVote(proposalID, voterAddr, options, metadata)
err = keeper.Votes.Set(ctx, collections.Join(proposalID, voterAddr), vote)
err = k.Votes.Set(ctx, collections.Join(proposalID, voterAddr), vote)
if err != nil {
return err
}
// called after a vote on a proposal is cast
err = keeper.Hooks().AfterProposalVote(ctx, proposalID, voterAddr)
err = k.Hooks().AfterProposalVote(ctx, proposalID, voterAddr)
if err != nil {
return err
}
@ -73,9 +94,9 @@ func (keeper Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr s
}
// deleteVotes deletes all the votes from a given proposalID.
func (keeper Keeper) deleteVotes(ctx context.Context, proposalID uint64) error {
func (k Keeper) deleteVotes(ctx context.Context, proposalID uint64) error {
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposalID)
err := keeper.Votes.Clear(ctx, rng)
err := k.Votes.Clear(ctx, rng)
if err != nil {
return err
}

View File

@ -14,6 +14,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
var invalidOption v1.VoteOption = 0x10
func TestVotes(t *testing.T) {
govKeeper, mocks, _, ctx := setupGovKeeper(t)
authKeeper, bankKeeper, stakingKeeper := mocks.acctKeeper, mocks.bankKeeper, mocks.stakingKeeper
@ -26,8 +28,6 @@ func TestVotes(t *testing.T) {
proposalID := proposal.Id
metadata := "metadata"
var invalidOption v1.VoteOption = 0x10
require.Error(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), metadata), "proposal not on voting period")
require.Error(t, govKeeper.AddVote(ctx, 10, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), ""), "invalid proposal ID")
@ -106,3 +106,33 @@ func TestVotes(t *testing.T) {
_, err = govKeeper.Votes.Get(ctx, collections.Join(proposalID+100, addrs[1]))
require.ErrorIs(t, err, collections.ErrNotFound)
}
func TestVotes_MultipleChoiceProposal(t *testing.T) {
govKeeper, mocks, _, ctx := setupGovKeeper(t)
authKeeper, bankKeeper, stakingKeeper := mocks.acctKeeper, mocks.bankKeeper, mocks.stakingKeeper
addrs := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, sdkmath.NewInt(10000000))
authKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
proposal, err := govKeeper.SubmitProposal(ctx, nil, "", "title", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), v1.ProposalType_PROPOSAL_TYPE_MULTIPLE_CHOICE)
require.NoError(t, err)
err = govKeeper.ProposalVoteOptions.Set(ctx, proposal.Id, v1.ProposalVoteOptions{
OptionOne: "Vote for @tac0turle",
OptionTwo: "Vote for @facudomedica",
OptionThree: "Vote for @alexanderbez",
})
require.NoError(t, err)
proposal.Status = v1.StatusVotingPeriod
require.NoError(t, govKeeper.SetProposal(ctx, proposal))
proposalID := proposal.Id
// invalid options
require.Error(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(invalidOption), ""), "invalid option")
require.Error(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionFour), ""), "invalid option") // option four is not defined.
// valid options
require.NoError(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionOne), ""))
require.NoError(t, govKeeper.AddVote(ctx, proposalID, addrs[1], v1.NewNonSplitVoteOption(v1.OptionTwo), ""))
require.NoError(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionThree), ""))
}

View File

@ -25,4 +25,5 @@ var (
VotesKeyPrefix = collections.NewPrefix(32) // VotesKeyPrefix stores the votes of proposals.
ParamsKey = collections.NewPrefix(48) // ParamsKey stores the module's params.
ConstitutionKey = collections.NewPrefix(49) // ConstitutionKey stores a chain's constitution.
ProposalVoteOptionsKeyPrefix = collections.NewPrefix(50) // ProposalVoteOptionsKeyPrefix stores the vote options of proposals.
)

View File

@ -12,6 +12,7 @@ import (
// governance module.
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
legacy.RegisterAminoMsg(cdc, &MsgSubmitProposal{}, "cosmos-sdk/v1/MsgSubmitProposal")
legacy.RegisterAminoMsg(cdc, &MsgSubmitMultipleChoiceProposal{}, "gov/MsgSubmitMultipleChoiceProposal")
legacy.RegisterAminoMsg(cdc, &MsgDeposit{}, "cosmos-sdk/v1/MsgDeposit")
legacy.RegisterAminoMsg(cdc, &MsgVote{}, "cosmos-sdk/v1/MsgVote")
legacy.RegisterAminoMsg(cdc, &MsgVoteWeighted{}, "cosmos-sdk/v1/MsgVoteWeighted")
@ -23,6 +24,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil),
&MsgSubmitProposal{},
&MsgSubmitMultipleChoiceProposal{},
&MsgVote{},
&MsgVoteWeighted{},
&MsgDeposit{},

View File

@ -351,7 +351,7 @@ type Proposal struct {
FailedReason string `protobuf:"bytes,15,opt,name=failed_reason,json=failedReason,proto3" json:"failed_reason,omitempty"`
// proposal_type defines the type of the proposal
//
// Since: cosmos-sdk 0.51
// Since: x/gov v1.0.0
ProposalType ProposalType `protobuf:"varint,16,opt,name=proposal_type,json=proposalType,proto3,enum=cosmos.gov.v1.ProposalType" json:"proposal_type,omitempty"`
}
@ -501,6 +501,91 @@ func (m *Proposal) GetProposalType() ProposalType {
return ProposalType_PROPOSAL_TYPE_UNSPECIFIED
}
// ProposalVoteOptions defines the stringified vote options for proposals.
// This allows to support multiple choice options for a given proposal.
//
// Since: x/gov v1.0.0
type ProposalVoteOptions struct {
// option_one is the first option of the proposal
OptionOne string `protobuf:"bytes,1,opt,name=option_one,json=optionOne,proto3" json:"option_one,omitempty"`
// option_two is the second option of the proposal
OptionTwo string `protobuf:"bytes,2,opt,name=option_two,json=optionTwo,proto3" json:"option_two,omitempty"`
// option_three is the third option of the proposal
OptionThree string `protobuf:"bytes,3,opt,name=option_three,json=optionThree,proto3" json:"option_three,omitempty"`
// option_four is the fourth option of the proposal
OptionFour string `protobuf:"bytes,4,opt,name=option_four,json=optionFour,proto3" json:"option_four,omitempty"`
// option_spam is always present for all proposals.
OptionSpam string `protobuf:"bytes,5,opt,name=option_spam,json=optionSpam,proto3" json:"option_spam,omitempty"`
}
func (m *ProposalVoteOptions) Reset() { *m = ProposalVoteOptions{} }
func (m *ProposalVoteOptions) String() string { return proto.CompactTextString(m) }
func (*ProposalVoteOptions) ProtoMessage() {}
func (*ProposalVoteOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{3}
}
func (m *ProposalVoteOptions) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ProposalVoteOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ProposalVoteOptions.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 *ProposalVoteOptions) XXX_Merge(src proto.Message) {
xxx_messageInfo_ProposalVoteOptions.Merge(m, src)
}
func (m *ProposalVoteOptions) XXX_Size() int {
return m.Size()
}
func (m *ProposalVoteOptions) XXX_DiscardUnknown() {
xxx_messageInfo_ProposalVoteOptions.DiscardUnknown(m)
}
var xxx_messageInfo_ProposalVoteOptions proto.InternalMessageInfo
func (m *ProposalVoteOptions) GetOptionOne() string {
if m != nil {
return m.OptionOne
}
return ""
}
func (m *ProposalVoteOptions) GetOptionTwo() string {
if m != nil {
return m.OptionTwo
}
return ""
}
func (m *ProposalVoteOptions) GetOptionThree() string {
if m != nil {
return m.OptionThree
}
return ""
}
func (m *ProposalVoteOptions) GetOptionFour() string {
if m != nil {
return m.OptionFour
}
return ""
}
func (m *ProposalVoteOptions) GetOptionSpam() string {
if m != nil {
return m.OptionSpam
}
return ""
}
// TallyResult defines a standard tally for a governance proposal.
type TallyResult struct {
// yes_count is the number of yes votes on a proposal.
@ -519,7 +604,7 @@ func (m *TallyResult) Reset() { *m = TallyResult{} }
func (m *TallyResult) String() string { return proto.CompactTextString(m) }
func (*TallyResult) ProtoMessage() {}
func (*TallyResult) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{3}
return fileDescriptor_e05cb1c0d030febb, []int{4}
}
func (m *TallyResult) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -601,7 +686,7 @@ func (m *Vote) Reset() { *m = Vote{} }
func (m *Vote) String() string { return proto.CompactTextString(m) }
func (*Vote) ProtoMessage() {}
func (*Vote) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{4}
return fileDescriptor_e05cb1c0d030febb, []int{5}
}
func (m *Vote) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -673,7 +758,7 @@ func (m *DepositParams) Reset() { *m = DepositParams{} }
func (m *DepositParams) String() string { return proto.CompactTextString(m) }
func (*DepositParams) ProtoMessage() {}
func (*DepositParams) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{5}
return fileDescriptor_e05cb1c0d030febb, []int{6}
}
func (m *DepositParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -728,7 +813,7 @@ func (m *VotingParams) Reset() { *m = VotingParams{} }
func (m *VotingParams) String() string { return proto.CompactTextString(m) }
func (*VotingParams) ProtoMessage() {}
func (*VotingParams) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{6}
return fileDescriptor_e05cb1c0d030febb, []int{7}
}
func (m *VotingParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -782,7 +867,7 @@ func (m *TallyParams) Reset() { *m = TallyParams{} }
func (m *TallyParams) String() string { return proto.CompactTextString(m) }
func (*TallyParams) ProtoMessage() {}
func (*TallyParams) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{7}
return fileDescriptor_e05cb1c0d030febb, []int{8}
}
func (m *TallyParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -894,6 +979,8 @@ type Params struct {
// If the proposal is cancelled before the max cancel period, the deposit will be returned/burn to the
// depositors, according to the proposal_cancel_ratio and proposal_cancel_dest parameters.
// After the max cancel period, the proposal cannot be cancelled anymore.
//
// Since: x/gov v1.0.0
ProposalCancelMaxPeriod string `protobuf:"bytes,17,opt,name=proposal_cancel_max_period,json=proposalCancelMaxPeriod,proto3" json:"proposal_cancel_max_period,omitempty"`
// optimistic_authorized_addresses is an optional governance parameter that limits the authorized accounts than can
// submit optimistic proposals
@ -911,7 +998,7 @@ func (m *Params) Reset() { *m = Params{} }
func (m *Params) String() string { return proto.CompactTextString(m) }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_e05cb1c0d030febb, []int{8}
return fileDescriptor_e05cb1c0d030febb, []int{9}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -1080,6 +1167,7 @@ func init() {
proto.RegisterType((*WeightedVoteOption)(nil), "cosmos.gov.v1.WeightedVoteOption")
proto.RegisterType((*Deposit)(nil), "cosmos.gov.v1.Deposit")
proto.RegisterType((*Proposal)(nil), "cosmos.gov.v1.Proposal")
proto.RegisterType((*ProposalVoteOptions)(nil), "cosmos.gov.v1.ProposalVoteOptions")
proto.RegisterType((*TallyResult)(nil), "cosmos.gov.v1.TallyResult")
proto.RegisterType((*Vote)(nil), "cosmos.gov.v1.Vote")
proto.RegisterType((*DepositParams)(nil), "cosmos.gov.v1.DepositParams")
@ -1091,112 +1179,117 @@ func init() {
func init() { proto.RegisterFile("cosmos/gov/v1/gov.proto", fileDescriptor_e05cb1c0d030febb) }
var fileDescriptor_e05cb1c0d030febb = []byte{
// 1666 bytes of a gzipped FileDescriptorProto
// 1748 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0x4f, 0x73, 0xe3, 0x48,
0x15, 0x8f, 0x6c, 0xc7, 0x71, 0x5e, 0x6c, 0x47, 0xe9, 0x64, 0x36, 0x4a, 0xb2, 0x71, 0xb2, 0x61,
0x6b, 0x2b, 0x0c, 0x3b, 0x36, 0xd9, 0x65, 0x38, 0xec, 0x52, 0x05, 0xfe, 0xa3, 0x21, 0x1a, 0x92,
0xd8, 0xc8, 0x9a, 0x64, 0x86, 0x8b, 0x50, 0xac, 0x1e, 0x47, 0x60, 0xa9, 0x8d, 0xd4, 0xf6, 0xc6,
0x7c, 0x00, 0xce, 0x5b, 0x9c, 0x38, 0x51, 0xdc, 0xe0, 0xc8, 0x61, 0x8b, 0xcf, 0xb0, 0xc5, 0x81,
0xda, 0xda, 0x13, 0x17, 0x06, 0x6a, 0xe6, 0x40, 0xd5, 0x7e, 0x04, 0x4e, 0x54, 0xb7, 0x5a, 0x96,
0xe4, 0x78, 0x37, 0xc9, 0x5e, 0x12, 0xe9, 0xbd, 0xdf, 0xef, 0xf5, 0xeb, 0xf7, 0x7e, 0xaf, 0xdb,
0x36, 0x6c, 0xf6, 0x48, 0xe0, 0x92, 0xa0, 0xd6, 0x27, 0xe3, 0xda, 0xf8, 0x88, 0xfd, 0xab, 0x0e,
0x7d, 0x42, 0x09, 0x2a, 0x85, 0x8e, 0x2a, 0xb3, 0x8c, 0x8f, 0xb6, 0x2b, 0x02, 0x77, 0x69, 0x05,
0xb8, 0x36, 0x3e, 0xba, 0xc4, 0xd4, 0x3a, 0xaa, 0xf5, 0x88, 0xe3, 0x85, 0xf0, 0xed, 0x8d, 0x3e,
0xe9, 0x13, 0xfe, 0x58, 0x63, 0x4f, 0xc2, 0xba, 0xd7, 0x27, 0xa4, 0x3f, 0xc0, 0x35, 0xfe, 0x76,
0x39, 0x7a, 0x59, 0xa3, 0x8e, 0x8b, 0x03, 0x6a, 0xb9, 0x43, 0x01, 0xd8, 0x9a, 0x05, 0x58, 0xde,
0x44, 0xb8, 0x2a, 0xb3, 0x2e, 0x7b, 0xe4, 0x5b, 0xd4, 0x21, 0xd1, 0x8a, 0x5b, 0x61, 0x46, 0x66,
0xb8, 0xa8, 0xc8, 0x36, 0x74, 0xad, 0x59, 0xae, 0xe3, 0x91, 0x1a, 0xff, 0x1b, 0x9a, 0x0e, 0x08,
0xa0, 0x0b, 0xec, 0xf4, 0xaf, 0x28, 0xb6, 0xcf, 0x09, 0xc5, 0xed, 0x21, 0x8b, 0x84, 0x8e, 0x20,
0x4f, 0xf8, 0x93, 0x22, 0xed, 0x4b, 0x87, 0xe5, 0x0f, 0xb6, 0xaa, 0xa9, 0x5d, 0x57, 0x63, 0xa8,
0x2e, 0x80, 0xe8, 0x3d, 0xc8, 0x7f, 0xc2, 0x03, 0x29, 0x99, 0x7d, 0xe9, 0x70, 0xb9, 0x51, 0xfe,
0xf2, 0xb3, 0x47, 0x20, 0x58, 0x2d, 0xdc, 0xd3, 0x85, 0xf7, 0xe0, 0x4f, 0x12, 0x2c, 0xb5, 0xf0,
0x90, 0x04, 0x0e, 0x45, 0x7b, 0xb0, 0x32, 0xf4, 0xc9, 0x90, 0x04, 0xd6, 0xc0, 0x74, 0x6c, 0xbe,
0x56, 0x4e, 0x87, 0xc8, 0xa4, 0xd9, 0xe8, 0x87, 0xb0, 0x6c, 0x87, 0x58, 0xe2, 0x8b, 0xb8, 0xca,
0x97, 0x9f, 0x3d, 0xda, 0x10, 0x71, 0xeb, 0xb6, 0xed, 0xe3, 0x20, 0xe8, 0x52, 0xdf, 0xf1, 0xfa,
0x7a, 0x0c, 0x45, 0x3f, 0x82, 0xbc, 0xe5, 0x92, 0x91, 0x47, 0x95, 0xec, 0x7e, 0xf6, 0x70, 0x25,
0xce, 0x9f, 0xb5, 0xa9, 0x2a, 0xda, 0x54, 0x6d, 0x12, 0xc7, 0x6b, 0x2c, 0x7f, 0xfe, 0x6a, 0x6f,
0xe1, 0x2f, 0xff, 0xfd, 0xeb, 0x43, 0x49, 0x17, 0x9c, 0x83, 0xbf, 0xe7, 0xa1, 0xd0, 0x11, 0x49,
0xa0, 0x32, 0x64, 0xa6, 0xa9, 0x65, 0x1c, 0x1b, 0x7d, 0x1f, 0x0a, 0x2e, 0x0e, 0x02, 0xab, 0x8f,
0x03, 0x25, 0xc3, 0x83, 0x6f, 0x54, 0xc3, 0x8e, 0x54, 0xa3, 0x8e, 0x54, 0xeb, 0xde, 0x44, 0x9f,
0xa2, 0xd0, 0x63, 0xc8, 0x07, 0xd4, 0xa2, 0xa3, 0x40, 0xc9, 0xf2, 0x62, 0xee, 0xce, 0x14, 0x33,
0x5a, 0xaa, 0xcb, 0x41, 0xba, 0x00, 0xa3, 0x63, 0x40, 0x2f, 0x1d, 0xcf, 0x1a, 0x98, 0xd4, 0x1a,
0x0c, 0x26, 0xa6, 0x8f, 0x83, 0xd1, 0x80, 0x2a, 0xb9, 0x7d, 0xe9, 0x70, 0xe5, 0x83, 0xed, 0x99,
0x10, 0x06, 0x83, 0xe8, 0x1c, 0xa1, 0xcb, 0x9c, 0x95, 0xb0, 0xa0, 0x3a, 0xac, 0x04, 0xa3, 0x4b,
0xd7, 0xa1, 0x26, 0x93, 0x99, 0xb2, 0x28, 0x42, 0xcc, 0x66, 0x6d, 0x44, 0x1a, 0x6c, 0xe4, 0x3e,
0xfd, 0xf7, 0x9e, 0xa4, 0x43, 0x48, 0x62, 0x66, 0xf4, 0x14, 0x64, 0x51, 0x5d, 0x13, 0x7b, 0x76,
0x18, 0x27, 0x7f, 0xc7, 0x38, 0x65, 0xc1, 0x54, 0x3d, 0x9b, 0xc7, 0xd2, 0xa0, 0x44, 0x09, 0xb5,
0x06, 0xa6, 0xb0, 0x2b, 0x4b, 0xf7, 0xe8, 0x51, 0x91, 0x53, 0x23, 0x01, 0x9d, 0xc0, 0xda, 0x98,
0x50, 0xc7, 0xeb, 0x9b, 0x01, 0xb5, 0x7c, 0xb1, 0xbf, 0xc2, 0x1d, 0xf3, 0x5a, 0x0d, 0xa9, 0x5d,
0xc6, 0xe4, 0x89, 0x1d, 0x83, 0x30, 0xc5, 0x7b, 0x5c, 0xbe, 0x63, 0xac, 0x52, 0x48, 0x8c, 0xb6,
0xb8, 0xcd, 0x44, 0x42, 0x2d, 0xdb, 0xa2, 0x96, 0x02, 0x4c, 0xb6, 0xfa, 0xf4, 0x1d, 0x6d, 0xc0,
0x22, 0x75, 0xe8, 0x00, 0x2b, 0x2b, 0xdc, 0x11, 0xbe, 0x20, 0x05, 0x96, 0x82, 0x91, 0xeb, 0x5a,
0xfe, 0x44, 0x29, 0x72, 0x7b, 0xf4, 0x8a, 0x7e, 0x00, 0x85, 0x70, 0x22, 0xb0, 0xaf, 0x94, 0x6e,
0x19, 0x81, 0x29, 0x12, 0xed, 0xc3, 0x32, 0xbe, 0x1e, 0x62, 0xdb, 0xa1, 0xd8, 0x56, 0xca, 0xfb,
0xd2, 0x61, 0xa1, 0x91, 0x51, 0x24, 0x3d, 0x36, 0xa2, 0xef, 0x40, 0xe9, 0xa5, 0xe5, 0x0c, 0xb0,
0x6d, 0xfa, 0xd8, 0x0a, 0x88, 0xa7, 0xac, 0xf2, 0x75, 0x8b, 0xa1, 0x51, 0xe7, 0x36, 0xf4, 0x13,
0x28, 0x4d, 0x27, 0x94, 0x4e, 0x86, 0x58, 0x91, 0xb9, 0x84, 0x77, 0xbe, 0x46, 0xc2, 0xc6, 0x64,
0x88, 0xf5, 0xe2, 0x30, 0xf1, 0x76, 0xf0, 0xbb, 0x0c, 0xac, 0x24, 0xc5, 0xf8, 0x3d, 0x58, 0x9e,
0xe0, 0xc0, 0xec, 0xf1, 0xe9, 0x94, 0x6e, 0x1c, 0x15, 0x9a, 0x47, 0xf5, 0xc2, 0x04, 0x07, 0x4d,
0xe6, 0x47, 0x1f, 0x42, 0xc9, 0xba, 0x0c, 0xa8, 0xe5, 0x78, 0x82, 0x90, 0x99, 0x4b, 0x28, 0x0a,
0x50, 0x48, 0xfa, 0x2e, 0x14, 0x3c, 0x22, 0xf0, 0xd9, 0xb9, 0xf8, 0x25, 0x8f, 0x84, 0xd0, 0x8f,
0x01, 0x79, 0xc4, 0xfc, 0xc4, 0xa1, 0x57, 0xe6, 0x18, 0xd3, 0x88, 0x94, 0x9b, 0x4b, 0x5a, 0xf5,
0xc8, 0x85, 0x43, 0xaf, 0xce, 0x31, 0x15, 0xe4, 0x47, 0x00, 0xc1, 0xd0, 0x72, 0x05, 0x69, 0x71,
0x2e, 0x69, 0x99, 0x21, 0x38, 0xfc, 0xe0, 0x6f, 0x12, 0xe4, 0xd8, 0xb9, 0x79, 0xfb, 0xa9, 0x57,
0x85, 0xc5, 0x31, 0xa1, 0xf8, 0xf6, 0x13, 0x2f, 0x84, 0xa1, 0x8f, 0x61, 0x29, 0x3c, 0x84, 0x03,
0x25, 0xc7, 0x47, 0xe9, 0x9d, 0x99, 0xf6, 0xdc, 0x3c, 0xe1, 0xf5, 0x88, 0x91, 0x92, 0xea, 0x62,
0x5a, 0xaa, 0x4f, 0x73, 0x85, 0xac, 0x9c, 0x3b, 0xf8, 0x97, 0x04, 0x25, 0x31, 0x70, 0x1d, 0xcb,
0xb7, 0xdc, 0x00, 0xbd, 0x80, 0x15, 0xd7, 0xf1, 0xa6, 0xf3, 0x2b, 0xdd, 0x36, 0xbf, 0xbb, 0x6c,
0x7e, 0xbf, 0x7a, 0xb5, 0xf7, 0x20, 0xc1, 0x7a, 0x9f, 0xb8, 0x0e, 0xc5, 0xee, 0x90, 0x4e, 0x74,
0x70, 0x1d, 0x2f, 0x9a, 0x68, 0x17, 0x90, 0x6b, 0x5d, 0x47, 0x20, 0x73, 0x88, 0x7d, 0x87, 0xd8,
0xbc, 0x10, 0x6c, 0x85, 0xd9, 0x31, 0x6c, 0x89, 0xab, 0xaf, 0xf1, 0xee, 0x57, 0xaf, 0xf6, 0xde,
0xbe, 0x49, 0x8c, 0x17, 0xf9, 0x03, 0x9b, 0x52, 0xd9, 0xb5, 0xae, 0xa3, 0x9d, 0x70, 0xff, 0x47,
0x19, 0x45, 0x3a, 0x78, 0x0e, 0xc5, 0x73, 0x3e, 0xbd, 0x62, 0x77, 0x2d, 0x10, 0xd3, 0x1c, 0xad,
0x2e, 0xdd, 0xb6, 0x7a, 0x8e, 0x47, 0x2f, 0x86, 0xac, 0x44, 0xe4, 0x3f, 0x4a, 0x42, 0xfb, 0x22,
0xf2, 0x7b, 0x90, 0xff, 0xcd, 0x88, 0xf8, 0x23, 0x77, 0x8e, 0xf0, 0xf9, 0x1d, 0x19, 0x7a, 0xd1,
0xfb, 0xb0, 0x4c, 0xaf, 0x7c, 0x1c, 0x5c, 0x91, 0x81, 0xfd, 0x35, 0xd7, 0x69, 0x0c, 0x40, 0x8f,
0xa1, 0xcc, 0xc5, 0x1b, 0x53, 0xb2, 0x73, 0x29, 0x25, 0x86, 0x32, 0x22, 0x10, 0x4f, 0xf0, 0xf7,
0x00, 0x79, 0x91, 0x9b, 0x7a, 0xcf, 0x9e, 0x26, 0xce, 0xe4, 0x64, 0xff, 0x4e, 0xbf, 0x5d, 0xff,
0x72, 0xf3, 0xfb, 0x73, 0xb3, 0x17, 0xd9, 0x6f, 0xd1, 0x8b, 0x44, 0xdd, 0x73, 0x77, 0xaf, 0xfb,
0xe2, 0xfd, 0xeb, 0x9e, 0xbf, 0x43, 0xdd, 0x91, 0x06, 0x5b, 0xac, 0xd0, 0x8e, 0xe7, 0x50, 0x27,
0xbe, 0x04, 0x4d, 0x9e, 0xbe, 0xb2, 0x34, 0x37, 0xc2, 0x5b, 0xae, 0xe3, 0x69, 0x21, 0x5e, 0x94,
0x47, 0x67, 0x68, 0xd4, 0x80, 0x07, 0xd3, 0x93, 0xa4, 0x67, 0x79, 0x3d, 0x3c, 0x10, 0x61, 0x0a,
0x73, 0xc3, 0xac, 0x47, 0xe0, 0x26, 0xc7, 0x86, 0x31, 0x9e, 0xc2, 0xc6, 0x6c, 0x0c, 0x1b, 0x07,
0x94, 0xdf, 0x7c, 0xdf, 0x74, 0xf6, 0xa0, 0x74, 0xb0, 0x16, 0x0e, 0x28, 0xba, 0x80, 0xcd, 0xe9,
0xfd, 0x62, 0xa6, 0xfb, 0x06, 0x77, 0xeb, 0xdb, 0x83, 0x29, 0xff, 0x3c, 0xd9, 0xc0, 0x1f, 0xc3,
0x7a, 0x1c, 0x38, 0xae, 0xf7, 0xca, 0xdc, 0x6d, 0xa2, 0x29, 0x34, 0x2e, 0xfa, 0x73, 0x88, 0x23,
0x9b, 0x49, 0x9d, 0x17, 0xef, 0xa1, 0xf3, 0x38, 0x87, 0xd3, 0x58, 0xf0, 0x87, 0x20, 0x5f, 0x8e,
0x7c, 0x8f, 0x6d, 0x17, 0x9b, 0x42, 0x65, 0xec, 0x9a, 0x2e, 0xe8, 0x65, 0x66, 0x67, 0x47, 0xee,
0xcf, 0x43, 0x75, 0xd5, 0x61, 0x97, 0x23, 0xa7, 0xe5, 0x9e, 0x0e, 0x89, 0x8f, 0x19, 0x3b, 0xbc,
0xa6, 0xf5, 0x6d, 0x06, 0x8a, 0x2e, 0xd4, 0x68, 0x1a, 0x42, 0x04, 0x7a, 0x17, 0xca, 0xf1, 0x62,
0x4c, 0x56, 0xfc, 0xd2, 0x2e, 0xe8, 0xc5, 0x68, 0x29, 0x76, 0x3b, 0xa1, 0x8f, 0x60, 0x2d, 0xb1,
0x45, 0x21, 0x09, 0x79, 0x6e, 0xad, 0x56, 0xe3, 0xd1, 0x0d, 0xe5, 0xf0, 0x33, 0xd8, 0x9e, 0x95,
0x03, 0x9b, 0x67, 0xd1, 0xc5, 0xb5, 0xb9, 0x41, 0x36, 0xd3, 0x52, 0x38, 0xb5, 0xae, 0x45, 0xdb,
0x7e, 0x09, 0x7b, 0xec, 0x9a, 0x71, 0x9d, 0x80, 0x3a, 0x3d, 0xd3, 0x1a, 0xd1, 0x2b, 0xe2, 0x3b,
0xbf, 0xc5, 0xb6, 0x69, 0x85, 0x52, 0xc2, 0x81, 0x82, 0xf6, 0xb3, 0xdf, 0x28, 0xb3, 0xdd, 0x38,
0x40, 0x7d, 0xca, 0xaf, 0x47, 0x74, 0xa4, 0x43, 0x02, 0x60, 0xfa, 0xf8, 0x57, 0xb8, 0x97, 0x96,
0xc8, 0xfa, 0xdc, 0x8c, 0x77, 0x62, 0x92, 0x2e, 0x38, 0x53, 0xad, 0x3c, 0xfc, 0xb3, 0x04, 0xc5,
0xe4, 0x07, 0x1a, 0xb4, 0x0b, 0x5b, 0x1d, 0xbd, 0xdd, 0x69, 0x77, 0xeb, 0x27, 0xa6, 0xf1, 0xa2,
0xa3, 0x9a, 0xcf, 0xce, 0xba, 0x1d, 0xb5, 0xa9, 0x3d, 0xd1, 0xd4, 0x96, 0xbc, 0x80, 0xb6, 0xe1,
0xad, 0xb4, 0xbb, 0x6b, 0xd4, 0xcf, 0x5a, 0x75, 0xbd, 0x25, 0x4b, 0xe8, 0x1d, 0xd8, 0x4d, 0xfb,
0x4e, 0x9f, 0x9d, 0x18, 0x5a, 0xe7, 0x44, 0x35, 0x9b, 0xc7, 0x6d, 0xad, 0xa9, 0xca, 0x19, 0xf4,
0x36, 0x28, 0x69, 0x48, 0xbb, 0x63, 0x68, 0xa7, 0x5a, 0xd7, 0xd0, 0x9a, 0x72, 0x16, 0xed, 0xc0,
0x66, 0xda, 0xab, 0x3e, 0xef, 0xa8, 0x2d, 0xcd, 0x50, 0x5b, 0x72, 0xee, 0xe1, 0xff, 0x24, 0x80,
0xc4, 0xb7, 0xb6, 0x1d, 0xd8, 0x3c, 0x6f, 0x1b, 0x61, 0x80, 0xf6, 0xd9, 0x4c, 0x96, 0xeb, 0xb0,
0x9a, 0x74, 0xb6, 0xcf, 0x54, 0x59, 0x9a, 0x35, 0xbe, 0x50, 0xbb, 0x37, 0x8d, 0xc6, 0x45, 0x5b,
0xce, 0xa0, 0x4d, 0x58, 0x4f, 0x1a, 0xeb, 0x8d, 0xae, 0x51, 0xd7, 0xce, 0xe4, 0x0c, 0x7a, 0x00,
0x6b, 0x29, 0xf4, 0xb1, 0xae, 0xaa, 0x72, 0x16, 0x21, 0x28, 0x27, 0xcd, 0x67, 0x6d, 0x39, 0x8b,
0x36, 0x40, 0x4e, 0xda, 0x9e, 0xb4, 0x9f, 0xe9, 0x72, 0x8e, 0xed, 0x3f, 0x8d, 0x34, 0x2f, 0x34,
0xe3, 0xd8, 0x3c, 0x57, 0x8d, 0xb6, 0x9c, 0x9b, 0xe5, 0x74, 0x3b, 0xf5, 0x53, 0x79, 0x71, 0x3b,
0x23, 0x4b, 0x0f, 0xff, 0x21, 0x41, 0x39, 0xfd, 0xd5, 0x09, 0xed, 0xc1, 0xce, 0xb4, 0x58, 0x5d,
0xa3, 0x6e, 0x3c, 0xeb, 0xce, 0x14, 0xe1, 0x00, 0x2a, 0xb3, 0x80, 0x96, 0xda, 0x69, 0x77, 0x35,
0xc3, 0xec, 0xa8, 0xba, 0xd6, 0x9e, 0x6d, 0x99, 0xc0, 0x9c, 0xb7, 0x0d, 0xed, 0xec, 0xa7, 0x11,
0x24, 0x93, 0xea, 0xb8, 0x80, 0x74, 0xea, 0xdd, 0xae, 0xda, 0x92, 0xb3, 0xa9, 0x76, 0x0a, 0x9f,
0xae, 0x3e, 0x55, 0x9b, 0xbc, 0x63, 0xf3, 0x98, 0x4f, 0xea, 0xda, 0x89, 0xda, 0x92, 0x17, 0x1b,
0x8f, 0x3f, 0x7f, 0x5d, 0x91, 0xbe, 0x78, 0x5d, 0x91, 0xfe, 0xf3, 0xba, 0x22, 0x7d, 0xfa, 0xa6,
0xb2, 0xf0, 0xc5, 0x9b, 0xca, 0xc2, 0x3f, 0xdf, 0x54, 0x16, 0x7e, 0xb1, 0x13, 0x4a, 0x37, 0xb0,
0x7f, 0x5d, 0x75, 0x48, 0xed, 0x9a, 0xff, 0x28, 0xc1, 0x3e, 0x8d, 0x07, 0xb5, 0xf1, 0xd1, 0x65,
0x9e, 0x9f, 0xa5, 0x1f, 0xfe, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xb1, 0x81, 0x9b, 0xb2, 0x10,
0x00, 0x00,
0x15, 0x8f, 0x6c, 0xc7, 0xb1, 0x9f, 0xff, 0x44, 0xe9, 0x64, 0x36, 0x4a, 0xb2, 0x71, 0x32, 0x66,
0x6b, 0x2b, 0x0c, 0x3b, 0x36, 0xd9, 0x65, 0x38, 0xec, 0x52, 0x05, 0x4e, 0xac, 0x21, 0x1a, 0x92,
0xd8, 0xc8, 0x9a, 0x64, 0x86, 0x8b, 0x50, 0xa2, 0x1e, 0x47, 0x60, 0xa9, 0x8d, 0xd4, 0xce, 0xc4,
0x7c, 0x00, 0xce, 0x5b, 0x9c, 0x38, 0x51, 0xdc, 0xe0, 0xc8, 0x61, 0x8b, 0xe2, 0x23, 0x6c, 0x71,
0xa0, 0xb6, 0xf6, 0xc4, 0x85, 0x81, 0x9a, 0x39, 0x50, 0xb5, 0x1f, 0x81, 0xd3, 0x56, 0xb7, 0x5a,
0x96, 0xe4, 0x78, 0x37, 0xc9, 0x5c, 0x66, 0xac, 0xf7, 0x7e, 0xbf, 0xd7, 0xdd, 0xef, 0xfd, 0xde,
0x6b, 0x29, 0xb0, 0x7a, 0x4e, 0x02, 0x97, 0x04, 0xcd, 0x3e, 0xb9, 0x6c, 0x5e, 0xee, 0xb2, 0xff,
0x1a, 0x43, 0x9f, 0x50, 0x82, 0x2a, 0xa1, 0xa3, 0xc1, 0x2c, 0x97, 0xbb, 0xeb, 0x35, 0x81, 0x3b,
0xb3, 0x02, 0xdc, 0xbc, 0xdc, 0x3d, 0xc3, 0xd4, 0xda, 0x6d, 0x9e, 0x13, 0xc7, 0x0b, 0xe1, 0xeb,
0x2b, 0x7d, 0xd2, 0x27, 0xfc, 0x67, 0x93, 0xfd, 0x12, 0xd6, 0xad, 0x3e, 0x21, 0xfd, 0x01, 0x6e,
0xf2, 0xa7, 0xb3, 0xd1, 0x8b, 0x26, 0x75, 0x5c, 0x1c, 0x50, 0xcb, 0x1d, 0x0a, 0xc0, 0xda, 0x34,
0xc0, 0xf2, 0xc6, 0xc2, 0x55, 0x9b, 0x76, 0xd9, 0x23, 0xdf, 0xa2, 0x0e, 0x89, 0x56, 0x5c, 0x0b,
0x77, 0x64, 0x86, 0x8b, 0x8a, 0xdd, 0x86, 0xae, 0x25, 0xcb, 0x75, 0x3c, 0xd2, 0xe4, 0xff, 0x86,
0xa6, 0x3a, 0x01, 0x74, 0x8a, 0x9d, 0xfe, 0x05, 0xc5, 0xf6, 0x09, 0xa1, 0xb8, 0x33, 0x64, 0x91,
0xd0, 0x2e, 0xe4, 0x09, 0xff, 0xa5, 0x48, 0xdb, 0xd2, 0x4e, 0xf5, 0xc3, 0xb5, 0x46, 0xea, 0xd4,
0x8d, 0x18, 0xaa, 0x0b, 0x20, 0x7a, 0x1f, 0xf2, 0x2f, 0x79, 0x20, 0x25, 0xb3, 0x2d, 0xed, 0x14,
0xf7, 0xaa, 0x5f, 0x7e, 0xf6, 0x10, 0x04, 0xab, 0x8d, 0xcf, 0x75, 0xe1, 0xad, 0xff, 0x49, 0x82,
0x85, 0x36, 0x1e, 0x92, 0xc0, 0xa1, 0x68, 0x0b, 0x4a, 0x43, 0x9f, 0x0c, 0x49, 0x60, 0x0d, 0x4c,
0xc7, 0xe6, 0x6b, 0xe5, 0x74, 0x88, 0x4c, 0x9a, 0x8d, 0x7e, 0x08, 0x45, 0x3b, 0xc4, 0x12, 0x5f,
0xc4, 0x55, 0xbe, 0xfc, 0xec, 0xe1, 0x8a, 0x88, 0xdb, 0xb2, 0x6d, 0x1f, 0x07, 0x41, 0x8f, 0xfa,
0x8e, 0xd7, 0xd7, 0x63, 0x28, 0xfa, 0x11, 0xe4, 0x2d, 0x97, 0x8c, 0x3c, 0xaa, 0x64, 0xb7, 0xb3,
0x3b, 0xa5, 0x78, 0xff, 0xac, 0x4c, 0x0d, 0x51, 0xa6, 0xc6, 0x3e, 0x71, 0xbc, 0xbd, 0xe2, 0xe7,
0xaf, 0xb6, 0xe6, 0xfe, 0xf2, 0xbf, 0xbf, 0x3e, 0x90, 0x74, 0xc1, 0xa9, 0xff, 0x23, 0x0f, 0x85,
0xae, 0xd8, 0x04, 0xaa, 0x42, 0x66, 0xb2, 0xb5, 0x8c, 0x63, 0xa3, 0xef, 0x43, 0xc1, 0xc5, 0x41,
0x60, 0xf5, 0x71, 0xa0, 0x64, 0x78, 0xf0, 0x95, 0x46, 0x58, 0x91, 0x46, 0x54, 0x91, 0x46, 0xcb,
0x1b, 0xeb, 0x13, 0x14, 0x7a, 0x04, 0xf9, 0x80, 0x5a, 0x74, 0x14, 0x28, 0x59, 0x9e, 0xcc, 0xcd,
0xa9, 0x64, 0x46, 0x4b, 0xf5, 0x38, 0x48, 0x17, 0x60, 0x74, 0x00, 0xe8, 0x85, 0xe3, 0x59, 0x03,
0x93, 0x5a, 0x83, 0xc1, 0xd8, 0xf4, 0x71, 0x30, 0x1a, 0x50, 0x25, 0xb7, 0x2d, 0xed, 0x94, 0x3e,
0x5c, 0x9f, 0x0a, 0x61, 0x30, 0x88, 0xce, 0x11, 0xba, 0xcc, 0x59, 0x09, 0x0b, 0x6a, 0x41, 0x29,
0x18, 0x9d, 0xb9, 0x0e, 0x35, 0x99, 0xcc, 0x94, 0x79, 0x11, 0x62, 0x7a, 0xd7, 0x46, 0xa4, 0xc1,
0xbd, 0xdc, 0xa7, 0xff, 0xd9, 0x92, 0x74, 0x08, 0x49, 0xcc, 0x8c, 0x9e, 0x80, 0x2c, 0xb2, 0x6b,
0x62, 0xcf, 0x0e, 0xe3, 0xe4, 0x6f, 0x19, 0xa7, 0x2a, 0x98, 0xaa, 0x67, 0xf3, 0x58, 0x1a, 0x54,
0x28, 0xa1, 0xd6, 0xc0, 0x14, 0x76, 0x65, 0xe1, 0x0e, 0x35, 0x2a, 0x73, 0x6a, 0x24, 0xa0, 0x43,
0x58, 0xba, 0x24, 0xd4, 0xf1, 0xfa, 0x66, 0x40, 0x2d, 0x5f, 0x9c, 0xaf, 0x70, 0xcb, 0x7d, 0x2d,
0x86, 0xd4, 0x1e, 0x63, 0xf2, 0x8d, 0x1d, 0x80, 0x30, 0xc5, 0x67, 0x2c, 0xde, 0x32, 0x56, 0x25,
0x24, 0x46, 0x47, 0x5c, 0x67, 0x22, 0xa1, 0x96, 0x6d, 0x51, 0x4b, 0x01, 0x26, 0x5b, 0x7d, 0xf2,
0x8c, 0x56, 0x60, 0x9e, 0x3a, 0x74, 0x80, 0x95, 0x12, 0x77, 0x84, 0x0f, 0x48, 0x81, 0x85, 0x60,
0xe4, 0xba, 0x96, 0x3f, 0x56, 0xca, 0xdc, 0x1e, 0x3d, 0xa2, 0x1f, 0x40, 0x21, 0xec, 0x08, 0xec,
0x2b, 0x95, 0x1b, 0x5a, 0x60, 0x82, 0x44, 0xdb, 0x50, 0xc4, 0x57, 0x43, 0x6c, 0x3b, 0x14, 0xdb,
0x4a, 0x75, 0x5b, 0xda, 0x29, 0xec, 0x65, 0x14, 0x49, 0x8f, 0x8d, 0xe8, 0x3b, 0x50, 0x79, 0x61,
0x39, 0x03, 0x6c, 0x9b, 0x3e, 0xb6, 0x02, 0xe2, 0x29, 0x8b, 0x7c, 0xdd, 0x72, 0x68, 0xd4, 0xb9,
0x0d, 0xfd, 0x04, 0x2a, 0x93, 0x0e, 0xa5, 0xe3, 0x21, 0x56, 0x64, 0x2e, 0xe1, 0x8d, 0x6f, 0x90,
0xb0, 0x31, 0x1e, 0x62, 0xbd, 0x3c, 0x4c, 0x3c, 0xd5, 0xff, 0x2e, 0xc1, 0x72, 0xe4, 0x8e, 0xc7,
0x46, 0x80, 0x36, 0x01, 0xc2, 0xc9, 0x61, 0x12, 0x0f, 0xf3, 0xfe, 0x2a, 0xea, 0xc5, 0xd0, 0xd2,
0xf1, 0x70, 0xc2, 0x4d, 0x5f, 0x92, 0xb0, 0xf5, 0x23, 0xb7, 0xf1, 0x92, 0xa0, 0xfb, 0x50, 0x8e,
0xdc, 0x17, 0x3e, 0xc6, 0xbc, 0xb3, 0x8a, 0x7a, 0x49, 0x00, 0x98, 0x89, 0x0d, 0x17, 0x01, 0x79,
0x41, 0x46, 0x3e, 0x6f, 0x9c, 0xa2, 0x2e, 0x82, 0x3e, 0x26, 0x23, 0x3f, 0x01, 0x08, 0x86, 0x96,
0xcb, 0xdb, 0x62, 0x02, 0xe8, 0x0d, 0x2d, 0xb7, 0xfe, 0xbb, 0x0c, 0x94, 0x92, 0x7d, 0xf4, 0x3d,
0x28, 0x8e, 0x71, 0x60, 0x9e, 0xf3, 0xc1, 0x22, 0x5d, 0x9b, 0x72, 0x9a, 0x47, 0xf5, 0xc2, 0x18,
0x07, 0xfb, 0xcc, 0x8f, 0x3e, 0x82, 0x8a, 0x75, 0x16, 0x50, 0xcb, 0xf1, 0x04, 0x21, 0x33, 0x93,
0x50, 0x16, 0xa0, 0x90, 0xf4, 0x5d, 0x28, 0x78, 0x44, 0xe0, 0xb3, 0x33, 0xf1, 0x0b, 0x1e, 0x09,
0xa1, 0x9f, 0x00, 0xf2, 0x88, 0xf9, 0xd2, 0xa1, 0x17, 0xe6, 0x25, 0xa6, 0x11, 0x29, 0x37, 0x93,
0xb4, 0xe8, 0x91, 0x53, 0x87, 0x5e, 0x9c, 0x60, 0x2a, 0xc8, 0x0f, 0x01, 0xd8, 0x99, 0x05, 0x69,
0x7e, 0x26, 0xa9, 0xc8, 0x10, 0x1c, 0x5e, 0xff, 0x9b, 0x04, 0x39, 0x56, 0xbb, 0x9b, 0x07, 0x76,
0x03, 0xe6, 0x2f, 0x09, 0xc5, 0x37, 0x0f, 0xeb, 0x10, 0x86, 0x3e, 0x81, 0x85, 0x30, 0xe1, 0x81,
0x92, 0xe3, 0x53, 0xe0, 0xfe, 0x94, 0xb2, 0xae, 0x5f, 0x4e, 0x7a, 0xc4, 0x48, 0x75, 0xd9, 0x7c,
0xba, 0xcb, 0x9e, 0xe4, 0x0a, 0x59, 0x39, 0x57, 0xff, 0xb7, 0x04, 0x15, 0x31, 0x2b, 0xba, 0x96,
0x6f, 0xb9, 0x01, 0x7a, 0x0e, 0x25, 0xd7, 0xf1, 0x26, 0xa3, 0x47, 0xba, 0x69, 0xf4, 0x6c, 0xb2,
0xd1, 0xf3, 0xd5, 0xab, 0xad, 0x7b, 0x09, 0xd6, 0x07, 0xc4, 0x75, 0x28, 0x76, 0x87, 0x74, 0xac,
0x83, 0xeb, 0x78, 0xd1, 0x30, 0x72, 0x01, 0xb9, 0xd6, 0x55, 0x04, 0x32, 0x87, 0xd8, 0x77, 0x88,
0xcd, 0x13, 0xc1, 0x56, 0x98, 0x9e, 0x20, 0x6d, 0x71, 0x6b, 0xef, 0xbd, 0xf7, 0xd5, 0xab, 0xad,
0x77, 0xaf, 0x13, 0xe3, 0x45, 0xfe, 0xc0, 0x06, 0x8c, 0xec, 0x5a, 0x57, 0xd1, 0x49, 0xb8, 0xff,
0xe3, 0x8c, 0x22, 0xd5, 0x9f, 0x41, 0xf9, 0x84, 0x0f, 0x1e, 0x71, 0xba, 0x36, 0x88, 0x41, 0x14,
0xad, 0x2e, 0xdd, 0xb4, 0x7a, 0x8e, 0x47, 0x2f, 0x87, 0xac, 0x44, 0xe4, 0x3f, 0x4a, 0x42, 0xfb,
0x22, 0xf2, 0xfb, 0x90, 0xff, 0xcd, 0x88, 0xf8, 0x23, 0x77, 0x86, 0xf0, 0xf9, 0xf5, 0x1e, 0x7a,
0xd1, 0x07, 0x50, 0x64, 0x1d, 0x19, 0x5c, 0x90, 0x81, 0xfd, 0x0d, 0x6f, 0x02, 0x31, 0x00, 0x3d,
0x82, 0x2a, 0x17, 0x6f, 0x4c, 0xc9, 0xce, 0xa4, 0x54, 0x18, 0xca, 0x88, 0x40, 0x7c, 0x83, 0xbf,
0x07, 0xc8, 0x8b, 0xbd, 0xa9, 0x77, 0xac, 0x69, 0xe2, 0x3a, 0x49, 0xd6, 0xef, 0xe8, 0xed, 0xea,
0x97, 0x9b, 0x5d, 0x9f, 0xeb, 0xb5, 0xc8, 0xbe, 0x45, 0x2d, 0x12, 0x79, 0xcf, 0xdd, 0x3e, 0xef,
0xf3, 0x77, 0xcf, 0x7b, 0xfe, 0x16, 0x79, 0x47, 0x1a, 0xac, 0xb1, 0x44, 0x3b, 0x9e, 0x43, 0x9d,
0xf8, 0xfe, 0x36, 0xf9, 0xf6, 0x95, 0x85, 0x99, 0x11, 0xde, 0x71, 0x1d, 0x4f, 0x0b, 0xf1, 0x22,
0x3d, 0x3a, 0x43, 0xa3, 0x3d, 0xb8, 0x37, 0x99, 0x24, 0xe7, 0x96, 0x77, 0x8e, 0x07, 0x22, 0x4c,
0x61, 0x66, 0x98, 0xe5, 0x08, 0xbc, 0xcf, 0xb1, 0x61, 0x8c, 0x27, 0xb0, 0x32, 0x1d, 0xc3, 0xc6,
0x01, 0xe5, 0x97, 0xf6, 0xb7, 0xcd, 0x1e, 0x94, 0x0e, 0xd6, 0xc6, 0x01, 0x45, 0xa7, 0xb0, 0x3a,
0xb9, 0x1a, 0xcd, 0x74, 0xdd, 0xe0, 0x76, 0x75, 0xbb, 0x37, 0xe1, 0x9f, 0x24, 0x0b, 0xf8, 0x63,
0x58, 0x8e, 0x03, 0xc7, 0xf9, 0x2e, 0xcd, 0x3c, 0x26, 0x9a, 0x40, 0xe3, 0xa4, 0x3f, 0x83, 0x38,
0xb2, 0x99, 0xd4, 0x79, 0xf9, 0x0e, 0x3a, 0x8f, 0xf7, 0x70, 0x14, 0x0b, 0x7e, 0x07, 0xe4, 0xb3,
0x91, 0xef, 0xb1, 0xe3, 0x62, 0x53, 0xa8, 0x8c, 0xbd, 0x61, 0x14, 0xf4, 0x2a, 0xb3, 0xb3, 0x91,
0xfb, 0xf3, 0x50, 0x5d, 0x2d, 0xd8, 0xe4, 0xc8, 0x49, 0xba, 0x27, 0x4d, 0xe2, 0x63, 0xc6, 0x0e,
0xdf, 0x30, 0xf4, 0x75, 0x06, 0x8a, 0x2e, 0xfb, 0xa8, 0x1b, 0x42, 0x04, 0x7a, 0x0f, 0xaa, 0xf1,
0x62, 0x4c, 0x56, 0xfc, 0x7d, 0xa3, 0xa0, 0x97, 0xa3, 0xa5, 0xd8, 0xed, 0x84, 0x3e, 0x86, 0xa5,
0xc4, 0x11, 0x85, 0x24, 0xe4, 0x99, 0xb9, 0x5a, 0x8c, 0x5b, 0x37, 0x94, 0xc3, 0xcf, 0x60, 0x7d,
0x5a, 0x0e, 0xac, 0x9f, 0x45, 0x15, 0x97, 0x66, 0x06, 0x59, 0x4d, 0x4b, 0xe1, 0xc8, 0xba, 0x12,
0x65, 0xfb, 0x25, 0x6c, 0xb1, 0x6b, 0xc6, 0x75, 0x02, 0xea, 0x9c, 0x9b, 0xd6, 0x88, 0x5e, 0x10,
0xdf, 0xf9, 0x2d, 0xb6, 0x4d, 0x2b, 0x94, 0x12, 0x0e, 0x14, 0xb4, 0x9d, 0xfd, 0x56, 0x99, 0x6d,
0xc6, 0x01, 0x5a, 0x13, 0x7e, 0x2b, 0xa2, 0x23, 0x1d, 0x12, 0x00, 0xd3, 0xc7, 0xbf, 0xc2, 0xe7,
0x69, 0x89, 0x2c, 0xcf, 0xdc, 0xf1, 0x46, 0x4c, 0xd2, 0x05, 0x67, 0xa2, 0x95, 0x07, 0x7f, 0x96,
0xa0, 0x9c, 0x7c, 0x17, 0x43, 0x9b, 0xb0, 0xd6, 0xd5, 0x3b, 0xdd, 0x4e, 0xaf, 0x75, 0x68, 0x1a,
0xcf, 0xbb, 0xaa, 0xf9, 0xf4, 0xb8, 0xd7, 0x55, 0xf7, 0xb5, 0xc7, 0x9a, 0xda, 0x96, 0xe7, 0xd0,
0x3a, 0xbc, 0x93, 0x76, 0xf7, 0x8c, 0xd6, 0x71, 0xbb, 0xa5, 0xb7, 0x65, 0x09, 0xdd, 0x87, 0xcd,
0xb4, 0xef, 0xe8, 0xe9, 0xa1, 0xa1, 0x75, 0x0f, 0x55, 0x73, 0xff, 0xa0, 0xa3, 0xed, 0xab, 0x72,
0x06, 0xbd, 0x0b, 0x4a, 0x1a, 0xd2, 0xe9, 0x1a, 0xda, 0x91, 0xd6, 0x33, 0xb4, 0x7d, 0x39, 0x8b,
0x36, 0x60, 0x35, 0xed, 0x55, 0x9f, 0x75, 0xd5, 0xb6, 0x66, 0xa8, 0x6d, 0x39, 0xf7, 0xe0, 0xff,
0x12, 0x40, 0xe2, 0x83, 0x73, 0x03, 0x56, 0x4f, 0x3a, 0x46, 0x18, 0xa0, 0x73, 0x3c, 0xb5, 0xcb,
0x65, 0x58, 0x4c, 0x3a, 0x3b, 0xc7, 0xaa, 0x2c, 0x4d, 0x1b, 0x9f, 0xab, 0xbd, 0xeb, 0x46, 0xe3,
0xb4, 0x23, 0x67, 0xd0, 0x2a, 0x2c, 0x27, 0x8d, 0xad, 0xbd, 0x9e, 0xd1, 0xd2, 0x8e, 0xe5, 0x0c,
0xba, 0x07, 0x4b, 0x29, 0xf4, 0x81, 0xae, 0xaa, 0x72, 0x16, 0x21, 0xa8, 0x26, 0xcd, 0xc7, 0x1d,
0x39, 0x8b, 0x56, 0x40, 0x4e, 0xda, 0x1e, 0x77, 0x9e, 0xea, 0x72, 0x8e, 0x9d, 0x3f, 0x8d, 0x34,
0x4f, 0x35, 0xe3, 0xc0, 0x3c, 0x51, 0x8d, 0x8e, 0x9c, 0x9b, 0xe6, 0xf4, 0xba, 0xad, 0x23, 0x79,
0x7e, 0x3d, 0x23, 0x4b, 0x0f, 0xfe, 0x29, 0x41, 0x35, 0xfd, 0xd5, 0x87, 0xb6, 0x60, 0x63, 0x92,
0xac, 0x9e, 0xd1, 0x32, 0x9e, 0xf6, 0xa6, 0x92, 0x50, 0x87, 0xda, 0x34, 0xa0, 0xad, 0x76, 0x3b,
0x3d, 0xcd, 0x30, 0xbb, 0xaa, 0xae, 0x75, 0xa6, 0x4b, 0x26, 0x30, 0x27, 0x1d, 0x43, 0x3b, 0xfe,
0x69, 0x04, 0xc9, 0xa4, 0x2a, 0x2e, 0x20, 0xdd, 0x56, 0xaf, 0xa7, 0xb6, 0xe5, 0x6c, 0xaa, 0x9c,
0xc2, 0xa7, 0xab, 0x4f, 0xd4, 0x7d, 0x5e, 0xb1, 0x59, 0xcc, 0xc7, 0x2d, 0xed, 0x50, 0x6d, 0xcb,
0xf3, 0x7b, 0x8f, 0x3e, 0x7f, 0x5d, 0x93, 0xbe, 0x78, 0x5d, 0x93, 0xfe, 0xfb, 0xba, 0x26, 0x7d,
0xfa, 0xa6, 0x36, 0xf7, 0xc5, 0x9b, 0xda, 0xdc, 0xbf, 0xde, 0xd4, 0xe6, 0x7e, 0xb1, 0x11, 0x4a,
0x37, 0xb0, 0x7f, 0xdd, 0x70, 0x48, 0xf3, 0x8a, 0xff, 0x3d, 0x85, 0x7d, 0x48, 0x04, 0xcd, 0xcb,
0xdd, 0xb3, 0x3c, 0x9f, 0xa5, 0x1f, 0x7d, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x38, 0x0a, 0x94, 0x69,
0x6d, 0x11, 0x00, 0x00,
}
func (m *WeightedVoteOption) Marshal() (dAtA []byte, err error) {
@ -1448,6 +1541,64 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *ProposalVoteOptions) 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 *ProposalVoteOptions) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ProposalVoteOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.OptionSpam) > 0 {
i -= len(m.OptionSpam)
copy(dAtA[i:], m.OptionSpam)
i = encodeVarintGov(dAtA, i, uint64(len(m.OptionSpam)))
i--
dAtA[i] = 0x2a
}
if len(m.OptionFour) > 0 {
i -= len(m.OptionFour)
copy(dAtA[i:], m.OptionFour)
i = encodeVarintGov(dAtA, i, uint64(len(m.OptionFour)))
i--
dAtA[i] = 0x22
}
if len(m.OptionThree) > 0 {
i -= len(m.OptionThree)
copy(dAtA[i:], m.OptionThree)
i = encodeVarintGov(dAtA, i, uint64(len(m.OptionThree)))
i--
dAtA[i] = 0x1a
}
if len(m.OptionTwo) > 0 {
i -= len(m.OptionTwo)
copy(dAtA[i:], m.OptionTwo)
i = encodeVarintGov(dAtA, i, uint64(len(m.OptionTwo)))
i--
dAtA[i] = 0x12
}
if len(m.OptionOne) > 0 {
i -= len(m.OptionOne)
copy(dAtA[i:], m.OptionOne)
i = encodeVarintGov(dAtA, i, uint64(len(m.OptionOne)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *TallyResult) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -2006,6 +2157,35 @@ func (m *Proposal) Size() (n int) {
return n
}
func (m *ProposalVoteOptions) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.OptionOne)
if l > 0 {
n += 1 + l + sovGov(uint64(l))
}
l = len(m.OptionTwo)
if l > 0 {
n += 1 + l + sovGov(uint64(l))
}
l = len(m.OptionThree)
if l > 0 {
n += 1 + l + sovGov(uint64(l))
}
l = len(m.OptionFour)
if l > 0 {
n += 1 + l + sovGov(uint64(l))
}
l = len(m.OptionSpam)
if l > 0 {
n += 1 + l + sovGov(uint64(l))
}
return n
}
func (m *TallyResult) Size() (n int) {
if m == nil {
return 0
@ -2979,6 +3159,216 @@ func (m *Proposal) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ProposalVoteOptions) 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 ErrIntOverflowGov
}
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: ProposalVoteOptions: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ProposalVoteOptions: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OptionOne", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGov
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGov
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGov
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OptionOne = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OptionTwo", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGov
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGov
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGov
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OptionTwo = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OptionThree", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGov
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGov
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGov
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OptionThree = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OptionFour", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGov
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGov
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGov
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OptionFour = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OptionSpam", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGov
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGov
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGov
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.OptionSpam = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGov(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGov
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *TallyResult) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -1,6 +1,8 @@
package v1
import (
"errors"
"cosmossdk.io/x/gov/types/v1beta1"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
@ -9,8 +11,8 @@ import (
)
var (
_, _, _, _, _, _, _ sdk.Msg = &MsgSubmitProposal{}, &MsgDeposit{}, &MsgVote{}, &MsgVoteWeighted{}, &MsgExecLegacyContent{}, &MsgUpdateParams{}, &MsgCancelProposal{}
_, _ codectypes.UnpackInterfacesMessage = &MsgSubmitProposal{}, &MsgExecLegacyContent{}
_, _, _, _, _, _, _, _ sdk.Msg = &MsgSubmitProposal{}, &MsgDeposit{}, &MsgVote{}, &MsgVoteWeighted{}, &MsgExecLegacyContent{}, &MsgUpdateParams{}, &MsgCancelProposal{}, &MsgSubmitMultipleChoiceProposal{}
_, _ codectypes.UnpackInterfacesMessage = &MsgSubmitProposal{}, &MsgExecLegacyContent{}
)
// NewMsgSubmitProposal creates a new MsgSubmitProposal.
@ -61,6 +63,28 @@ func (m MsgSubmitProposal) UnpackInterfaces(unpacker codectypes.AnyUnpacker) err
return sdktx.UnpackInterfaces(unpacker, m.Messages)
}
// NewMsgSubmitMultipleChoiceProposal creates a new MsgSubmitMultipleChoiceProposal.
func NewMultipleChoiceMsgSubmitProposal(
initialDeposit sdk.Coins,
proposer, metadata, title, summary string,
votingOptions *ProposalVoteOptions,
) (*MsgSubmitMultipleChoiceProposal, error) {
if votingOptions == nil {
return nil, errors.New("voting options cannot be nil")
}
m := &MsgSubmitMultipleChoiceProposal{
InitialDeposit: initialDeposit,
Proposer: proposer,
Metadata: metadata,
Title: title,
Summary: summary,
VoteOptions: votingOptions,
}
return m, nil
}
// NewMsgDeposit creates a new MsgDeposit instance
func NewMsgDeposit(depositor sdk.AccAddress, proposalID uint64, amount sdk.Coins) *MsgDeposit {
return &MsgDeposit{proposalID, depositor.String(), amount}

View File

@ -975,6 +975,98 @@ func (m *QueryTallyResultResponse) GetTally() *TallyResult {
return nil
}
// QueryProposalVoteOptionsRequest is the request type for the Query/ProposalVoteOptions RPC method.
type QueryProposalVoteOptionsRequest struct {
// proposal_id defines the unique id of the proposal.
ProposalId uint64 `protobuf:"varint,1,opt,name=proposal_id,json=proposalId,proto3" json:"proposal_id,omitempty"`
}
func (m *QueryProposalVoteOptionsRequest) Reset() { *m = QueryProposalVoteOptionsRequest{} }
func (m *QueryProposalVoteOptionsRequest) String() string { return proto.CompactTextString(m) }
func (*QueryProposalVoteOptionsRequest) ProtoMessage() {}
func (*QueryProposalVoteOptionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_46a436d1109b50d0, []int{18}
}
func (m *QueryProposalVoteOptionsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryProposalVoteOptionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryProposalVoteOptionsRequest.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 *QueryProposalVoteOptionsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryProposalVoteOptionsRequest.Merge(m, src)
}
func (m *QueryProposalVoteOptionsRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryProposalVoteOptionsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryProposalVoteOptionsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryProposalVoteOptionsRequest proto.InternalMessageInfo
func (m *QueryProposalVoteOptionsRequest) GetProposalId() uint64 {
if m != nil {
return m.ProposalId
}
return 0
}
// QueryProposalVoteOptionsResponse is the response type for the Query/ProposalVoteOptions RPC method.
type QueryProposalVoteOptionsResponse struct {
// vote_options defines the valid voting options for a proposal.
VoteOptions *ProposalVoteOptions `protobuf:"bytes,1,opt,name=vote_options,json=voteOptions,proto3" json:"vote_options,omitempty"`
}
func (m *QueryProposalVoteOptionsResponse) Reset() { *m = QueryProposalVoteOptionsResponse{} }
func (m *QueryProposalVoteOptionsResponse) String() string { return proto.CompactTextString(m) }
func (*QueryProposalVoteOptionsResponse) ProtoMessage() {}
func (*QueryProposalVoteOptionsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_46a436d1109b50d0, []int{19}
}
func (m *QueryProposalVoteOptionsResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryProposalVoteOptionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryProposalVoteOptionsResponse.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 *QueryProposalVoteOptionsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryProposalVoteOptionsResponse.Merge(m, src)
}
func (m *QueryProposalVoteOptionsResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryProposalVoteOptionsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryProposalVoteOptionsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryProposalVoteOptionsResponse proto.InternalMessageInfo
func (m *QueryProposalVoteOptionsResponse) GetVoteOptions() *ProposalVoteOptions {
if m != nil {
return m.VoteOptions
}
return nil
}
func init() {
proto.RegisterType((*QueryConstitutionRequest)(nil), "cosmos.gov.v1.QueryConstitutionRequest")
proto.RegisterType((*QueryConstitutionResponse)(nil), "cosmos.gov.v1.QueryConstitutionResponse")
@ -994,76 +1086,82 @@ func init() {
proto.RegisterType((*QueryDepositsResponse)(nil), "cosmos.gov.v1.QueryDepositsResponse")
proto.RegisterType((*QueryTallyResultRequest)(nil), "cosmos.gov.v1.QueryTallyResultRequest")
proto.RegisterType((*QueryTallyResultResponse)(nil), "cosmos.gov.v1.QueryTallyResultResponse")
proto.RegisterType((*QueryProposalVoteOptionsRequest)(nil), "cosmos.gov.v1.QueryProposalVoteOptionsRequest")
proto.RegisterType((*QueryProposalVoteOptionsResponse)(nil), "cosmos.gov.v1.QueryProposalVoteOptionsResponse")
}
func init() { proto.RegisterFile("cosmos/gov/v1/query.proto", fileDescriptor_46a436d1109b50d0) }
var fileDescriptor_46a436d1109b50d0 = []byte{
// 1013 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4b, 0x6f, 0xdc, 0x54,
0x14, 0x8e, 0x27, 0x8f, 0x66, 0x4e, 0x1e, 0xc0, 0xe9, 0x23, 0xae, 0xd3, 0x4e, 0x83, 0x43, 0x93,
0xf0, 0xa8, 0xcd, 0xa4, 0x4d, 0x2b, 0x41, 0x11, 0x6a, 0x5a, 0xa5, 0x20, 0xb1, 0x08, 0x6e, 0xc5,
0x82, 0x4d, 0xe4, 0x66, 0x2c, 0xcb, 0x62, 0xea, 0xeb, 0xce, 0xbd, 0x33, 0x22, 0xa4, 0x11, 0x52,
0x25, 0x1e, 0x2b, 0x40, 0xa2, 0x02, 0x7e, 0x08, 0x3f, 0x82, 0x65, 0x05, 0x1b, 0x96, 0x28, 0xe1,
0x87, 0x20, 0xdf, 0x7b, 0xec, 0xb1, 0x1d, 0x8f, 0x67, 0x52, 0x45, 0x2c, 0xe7, 0xde, 0xef, 0x7c,
0xe7, 0x3b, 0x8f, 0x7b, 0x8e, 0x07, 0x2e, 0xee, 0x32, 0xfe, 0x98, 0x71, 0xdb, 0x67, 0x3d, 0xbb,
0xd7, 0xb4, 0x9f, 0x74, 0xbd, 0xce, 0x9e, 0x15, 0x75, 0x98, 0x60, 0x38, 0xa7, 0xae, 0x2c, 0x9f,
0xf5, 0xac, 0x5e, 0xd3, 0x78, 0x8b, 0x90, 0x8f, 0x5c, 0xee, 0x29, 0x9c, 0xdd, 0x6b, 0x3e, 0xf2,
0x84, 0xdb, 0xb4, 0x23, 0xd7, 0x0f, 0x42, 0x57, 0x04, 0x2c, 0x54, 0xa6, 0xc6, 0x25, 0x9f, 0x31,
0xbf, 0xed, 0xd9, 0x6e, 0x14, 0xd8, 0x6e, 0x18, 0x32, 0x21, 0x2f, 0x39, 0xdd, 0x2e, 0xe4, 0x7d,
0xc6, 0xfc, 0xea, 0x82, 0xc4, 0xec, 0xc8, 0x5f, 0x36, 0xb9, 0x97, 0x3f, 0x4c, 0x03, 0xf4, 0x4f,
0x63, 0x9f, 0x77, 0x59, 0xc8, 0x45, 0x20, 0xba, 0x31, 0x9f, 0xe3, 0x3d, 0xe9, 0x7a, 0x5c, 0x98,
0x1f, 0xc2, 0xc5, 0x92, 0x3b, 0x1e, 0xb1, 0x90, 0x7b, 0x68, 0xc2, 0xec, 0x6e, 0xe6, 0x5c, 0xd7,
0x96, 0xb4, 0xb5, 0xba, 0x93, 0x3b, 0x33, 0x6f, 0xc1, 0x39, 0x49, 0xb0, 0xdd, 0x61, 0x11, 0xe3,
0x6e, 0x9b, 0x88, 0xf1, 0x0a, 0xcc, 0x44, 0x74, 0xb4, 0x13, 0xb4, 0xa4, 0xe9, 0x84, 0x03, 0xc9,
0xd1, 0xc7, 0x2d, 0xf3, 0x13, 0x38, 0x5f, 0x30, 0x24, 0xaf, 0xd7, 0x61, 0x3a, 0x81, 0x49, 0xb3,
0x99, 0xf5, 0x05, 0x2b, 0x97, 0x4e, 0x2b, 0x35, 0x49, 0x81, 0xe6, 0x8f, 0xb5, 0x02, 0x1d, 0x4f,
0x84, 0x6c, 0xc1, 0x2b, 0xa9, 0x10, 0x2e, 0x5c, 0xd1, 0xe5, 0x92, 0x75, 0x7e, 0xfd, 0xf2, 0x00,
0xd6, 0x07, 0x12, 0xe4, 0xcc, 0x47, 0xb9, 0xdf, 0x68, 0xc1, 0x64, 0x8f, 0x09, 0xaf, 0xa3, 0xd7,
0xe2, 0x2c, 0x6c, 0xea, 0x7f, 0xfe, 0x7e, 0xed, 0x1c, 0x11, 0xdc, 0x69, 0xb5, 0x3a, 0x1e, 0xe7,
0x0f, 0x44, 0x27, 0x08, 0x7d, 0x47, 0xc1, 0xf0, 0x26, 0xd4, 0x5b, 0x5e, 0xc4, 0x78, 0x20, 0x58,
0x47, 0x1f, 0x1f, 0x62, 0xd3, 0x87, 0xe2, 0x16, 0x40, 0xbf, 0x27, 0xf4, 0x09, 0x99, 0x80, 0x95,
0x44, 0x6a, 0xdc, 0x40, 0x96, 0x6a, 0x34, 0x6a, 0x20, 0x6b, 0xdb, 0xf5, 0x3d, 0x8a, 0xd5, 0xc9,
0x58, 0x9a, 0xbf, 0x69, 0x70, 0xa1, 0x98, 0x11, 0xca, 0xf0, 0x06, 0xd4, 0x93, 0xe0, 0xe2, 0x64,
0x8c, 0x57, 0xa5, 0xb8, 0x8f, 0xc4, 0xfb, 0x39, 0x65, 0x35, 0xa9, 0x6c, 0x75, 0xa8, 0x32, 0xe5,
0x33, 0x27, 0x6d, 0x17, 0x5e, 0x95, 0xca, 0x3e, 0x63, 0xc2, 0x1b, 0xb5, 0x5f, 0x4e, 0x9a, 0x7f,
0xf3, 0x36, 0xbc, 0x96, 0x71, 0x42, 0x91, 0xaf, 0xc2, 0x44, 0x7c, 0x4b, 0x7d, 0x75, 0xb6, 0x10,
0xb4, 0x84, 0x4a, 0x80, 0xf9, 0x34, 0x63, 0xcd, 0x47, 0xd6, 0xb8, 0x55, 0x92, 0xa1, 0x97, 0xa9,
0xdd, 0xf7, 0x1a, 0x60, 0xd6, 0x3d, 0xa9, 0x7f, 0x53, 0xa5, 0x20, 0xa9, 0x59, 0xa9, 0x7c, 0x85,
0x38, 0xbd, 0x5a, 0x6d, 0x90, 0x92, 0x6d, 0xb7, 0xe3, 0x3e, 0xce, 0x65, 0x42, 0x1e, 0xec, 0x88,
0xbd, 0xc8, 0xa3, 0xc1, 0x00, 0xea, 0xe8, 0xe1, 0x5e, 0xe4, 0x99, 0xbf, 0xd4, 0xe0, 0x6c, 0xce,
0x8e, 0x42, 0xb8, 0x07, 0x73, 0x3d, 0x26, 0x82, 0xd0, 0xdf, 0x51, 0x60, 0xaa, 0xc4, 0xe2, 0xf1,
0x50, 0x82, 0xd0, 0x57, 0xb6, 0x9b, 0x35, 0x5d, 0x73, 0x66, 0x7b, 0x99, 0x13, 0xbc, 0x0f, 0xf3,
0xf4, 0x60, 0x12, 0x1a, 0x15, 0xe1, 0xa5, 0x02, 0xcd, 0x3d, 0x05, 0xca, 0xf0, 0xcc, 0xb5, 0xb2,
0x47, 0x78, 0x07, 0x66, 0x85, 0xdb, 0x6e, 0xef, 0x25, 0x34, 0xe3, 0x92, 0xc6, 0x28, 0xd0, 0x3c,
0x8c, 0x21, 0x19, 0x92, 0x19, 0xd1, 0x3f, 0xc0, 0x6b, 0x30, 0x45, 0xc6, 0xea, 0xad, 0x9e, 0x2f,
0xbe, 0x24, 0x95, 0x00, 0x02, 0x99, 0x21, 0xe5, 0x85, 0xa4, 0x8d, 0xdc, 0x5a, 0xb9, 0x71, 0x52,
0x1b, 0x79, 0x9c, 0x98, 0x1f, 0xd1, 0x7c, 0x4e, 0xfd, 0x51, 0x21, 0xde, 0x85, 0x33, 0x04, 0xa2,
0x12, 0x5c, 0x28, 0xcf, 0x9d, 0x93, 0xc0, 0xcc, 0xaf, 0xf3, 0x4c, 0xff, 0xff, 0xab, 0x78, 0xae,
0xd1, 0x8c, 0xef, 0x2b, 0xa0, 0x60, 0xd6, 0x61, 0x9a, 0x54, 0x26, 0x6f, 0x63, 0x50, 0x34, 0x29,
0xee, 0xf4, 0x5e, 0xc8, 0x7b, 0xb0, 0x20, 0x55, 0xc9, 0x2e, 0x71, 0x3c, 0xde, 0x6d, 0x8b, 0x13,
0x2c, 0x41, 0xfd, 0xb8, 0x6d, 0x5a, 0xa1, 0x49, 0xd9, 0x67, 0x54, 0x9f, 0xd2, 0xa6, 0x24, 0x13,
0x05, 0x5c, 0x3f, 0xaa, 0xc3, 0xa4, 0xa4, 0xc3, 0x6f, 0x35, 0x98, 0xcd, 0xae, 0x74, 0x5c, 0x2d,
0x58, 0x0f, 0xfa, 0x20, 0x30, 0xd6, 0x86, 0x03, 0x95, 0x3e, 0x73, 0xf9, 0xd9, 0x5f, 0xff, 0xfe,
0x5c, 0xbb, 0x8c, 0x8b, 0x76, 0xfe, 0x9b, 0x24, 0xfb, 0x79, 0x80, 0xdf, 0x68, 0x30, 0x9d, 0xec,
0x12, 0x5c, 0x2e, 0xe3, 0x2e, 0x7c, 0x38, 0x18, 0x6f, 0x54, 0x83, 0xc8, 0xb9, 0x25, 0x9d, 0xaf,
0xe1, 0x4a, 0xc1, 0x79, 0xba, 0xad, 0xec, 0xfd, 0x4c, 0xe6, 0x0f, 0xf0, 0x2b, 0xa8, 0xa7, 0x7b,
0x10, 0x2b, 0x5d, 0x24, 0x7d, 0x6d, 0x5c, 0x1d, 0x82, 0x22, 0x25, 0x4b, 0x52, 0x89, 0x81, 0xfa,
0x20, 0x25, 0xf8, 0x9d, 0x06, 0x13, 0xf1, 0x6c, 0xc6, 0x2b, 0x65, 0x8c, 0x99, 0x25, 0x68, 0x2c,
0x0d, 0x06, 0x90, 0xb7, 0xdb, 0xd2, 0xdb, 0x4d, 0xbc, 0x31, 0x5a, 0xdc, 0xb6, 0xdc, 0x06, 0xf6,
0xbe, 0x5c, 0x89, 0x07, 0xf8, 0x4c, 0x83, 0x49, 0xb9, 0x52, 0x70, 0xa0, 0xa7, 0x34, 0xfc, 0xd7,
0x2b, 0x10, 0x24, 0xe6, 0x86, 0x14, 0x63, 0xe1, 0x3b, 0x27, 0x11, 0x83, 0x4f, 0x61, 0x8a, 0x46,
0x67, 0xa9, 0x8b, 0xdc, 0xa2, 0x31, 0xcc, 0x2a, 0x08, 0xc9, 0x78, 0x5b, 0xca, 0xb8, 0x8a, 0xcb,
0x45, 0x19, 0x12, 0x66, 0xef, 0x67, 0x36, 0xd5, 0x01, 0xfe, 0xaa, 0xc1, 0x19, 0x1a, 0x06, 0x58,
0x4a, 0x9e, 0x1f, 0xcc, 0xc6, 0x72, 0x25, 0x86, 0x14, 0xdc, 0x95, 0x0a, 0x3e, 0xc0, 0xf7, 0x47,
0x4c, 0x44, 0x32, 0x84, 0xec, 0xfd, 0x74, 0x50, 0x1f, 0xe0, 0x0f, 0x1a, 0x4c, 0x27, 0x93, 0x0d,
0xab, 0xdc, 0xf2, 0xca, 0xa7, 0x52, 0x1c, 0x8e, 0xe6, 0x2d, 0x29, 0xae, 0x89, 0xf6, 0x09, 0xc5,
0xe1, 0x73, 0x0d, 0x66, 0x32, 0x53, 0x06, 0x57, 0xca, 0xdc, 0x1d, 0x9f, 0x7a, 0xc6, 0xea, 0x50,
0xdc, 0x4b, 0xf6, 0x8f, 0x9c, 0x72, 0x9b, 0x1b, 0x7f, 0x1c, 0x36, 0xb4, 0x17, 0x87, 0x0d, 0xed,
0x9f, 0xc3, 0x86, 0xf6, 0xd3, 0x51, 0x63, 0xec, 0xc5, 0x51, 0x63, 0xec, 0xef, 0xa3, 0xc6, 0xd8,
0xe7, 0x8b, 0x8a, 0x86, 0xb7, 0xbe, 0xb0, 0x02, 0x66, 0x7f, 0x29, 0xe9, 0xe2, 0xaa, 0xf3, 0xf8,
0xdf, 0xd6, 0x94, 0xfc, 0x33, 0x74, 0xfd, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x87, 0x70, 0x46,
0xfc, 0xb6, 0x0d, 0x00, 0x00,
// 1086 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x5b, 0x6f, 0xdc, 0xc4,
0x17, 0x8f, 0x37, 0x97, 0x26, 0x67, 0x93, 0xfc, 0xff, 0x9c, 0xb4, 0xcd, 0xd6, 0x69, 0x37, 0x61,
0x42, 0x93, 0x70, 0xa9, 0xcd, 0x26, 0x4d, 0x2b, 0xd1, 0x22, 0xd4, 0xb4, 0xa4, 0x20, 0x21, 0x11,
0xb6, 0x15, 0x0f, 0xbc, 0xac, 0xdc, 0xac, 0xb5, 0xb2, 0xd8, 0x7a, 0xdc, 0x9d, 0xd9, 0x15, 0x21,
0x8d, 0x90, 0x2a, 0x71, 0x79, 0x02, 0x24, 0x2a, 0x2e, 0x9f, 0x03, 0x3e, 0x04, 0x8f, 0x15, 0xbc,
0xf0, 0x88, 0x12, 0x3e, 0x08, 0xf2, 0xcc, 0xb1, 0xd7, 0x76, 0xbc, 0xb7, 0xaa, 0xe2, 0xd1, 0x33,
0xbf, 0xf3, 0x3b, 0xbf, 0x39, 0xe7, 0xcc, 0x39, 0x63, 0xb8, 0xb0, 0xcf, 0xc5, 0x43, 0x2e, 0xec,
0x06, 0xef, 0xd8, 0x9d, 0x8a, 0xfd, 0xa8, 0xed, 0xb6, 0x0e, 0xac, 0xa0, 0xc5, 0x25, 0xc7, 0x39,
0xbd, 0x65, 0x35, 0x78, 0xc7, 0xea, 0x54, 0xcc, 0xd7, 0x08, 0xf9, 0xc0, 0x11, 0xae, 0xc6, 0xd9,
0x9d, 0xca, 0x03, 0x57, 0x3a, 0x15, 0x3b, 0x70, 0x1a, 0x9e, 0xef, 0x48, 0x8f, 0xfb, 0xda, 0xd4,
0xbc, 0xd8, 0xe0, 0xbc, 0xd1, 0x74, 0x6d, 0x27, 0xf0, 0x6c, 0xc7, 0xf7, 0xb9, 0x54, 0x9b, 0x82,
0x76, 0x17, 0xd3, 0x3e, 0x43, 0x7e, 0xbd, 0x41, 0x62, 0x6a, 0xea, 0xcb, 0x26, 0xf7, 0xea, 0x83,
0x99, 0x50, 0xfa, 0x28, 0xf4, 0x79, 0x9b, 0xfb, 0x42, 0x7a, 0xb2, 0x1d, 0xf2, 0x55, 0xdd, 0x47,
0x6d, 0x57, 0x48, 0xf6, 0x0e, 0x5c, 0xc8, 0xd9, 0x13, 0x01, 0xf7, 0x85, 0x8b, 0x0c, 0x66, 0xf7,
0x13, 0xeb, 0x25, 0x63, 0xc5, 0xd8, 0x98, 0xa9, 0xa6, 0xd6, 0xd8, 0x75, 0x38, 0xab, 0x08, 0xf6,
0x5a, 0x3c, 0xe0, 0xc2, 0x69, 0x12, 0x31, 0x2e, 0x43, 0x31, 0xa0, 0xa5, 0x9a, 0x57, 0x57, 0xa6,
0x13, 0x55, 0x88, 0x96, 0xde, 0xaf, 0xb3, 0x0f, 0xe0, 0x5c, 0xc6, 0x90, 0xbc, 0x6e, 0xc1, 0x74,
0x04, 0x53, 0x66, 0xc5, 0xcd, 0x45, 0x2b, 0x15, 0x4e, 0x2b, 0x36, 0x89, 0x81, 0xec, 0xbb, 0x42,
0x86, 0x4e, 0x44, 0x42, 0x76, 0xe1, 0x7f, 0xb1, 0x10, 0x21, 0x1d, 0xd9, 0x16, 0x8a, 0x75, 0x7e,
0xf3, 0x52, 0x0f, 0xd6, 0x7b, 0x0a, 0x54, 0x9d, 0x0f, 0x52, 0xdf, 0x68, 0xc1, 0x64, 0x87, 0x4b,
0xb7, 0x55, 0x2a, 0x84, 0x51, 0xd8, 0x29, 0xfd, 0xf1, 0xdb, 0x95, 0xb3, 0x44, 0x70, 0xab, 0x5e,
0x6f, 0xb9, 0x42, 0xdc, 0x93, 0x2d, 0xcf, 0x6f, 0x54, 0x35, 0x0c, 0xaf, 0xc1, 0x4c, 0xdd, 0x0d,
0xb8, 0xf0, 0x24, 0x6f, 0x95, 0xc6, 0x07, 0xd8, 0x74, 0xa1, 0xb8, 0x0b, 0xd0, 0xad, 0x89, 0xd2,
0x84, 0x0a, 0xc0, 0x5a, 0x24, 0x35, 0x2c, 0x20, 0x4b, 0x17, 0x1a, 0x15, 0x90, 0xb5, 0xe7, 0x34,
0x5c, 0x3a, 0x6b, 0x35, 0x61, 0xc9, 0x7e, 0x36, 0xe0, 0x7c, 0x36, 0x22, 0x14, 0xe1, 0x6d, 0x98,
0x89, 0x0e, 0x17, 0x06, 0x63, 0xbc, 0x5f, 0x88, 0xbb, 0x48, 0xbc, 0x9b, 0x52, 0x56, 0x50, 0xca,
0xd6, 0x07, 0x2a, 0xd3, 0x3e, 0x53, 0xd2, 0xf6, 0xe1, 0xff, 0x4a, 0xd9, 0xc7, 0x5c, 0xba, 0xc3,
0xd6, 0xcb, 0xa8, 0xf1, 0x67, 0x37, 0xe1, 0xa5, 0x84, 0x13, 0x3a, 0xf9, 0x3a, 0x4c, 0x84, 0xbb,
0x54, 0x57, 0x0b, 0x99, 0x43, 0x2b, 0xa8, 0x02, 0xb0, 0xc7, 0x09, 0x6b, 0x31, 0xb4, 0xc6, 0xdd,
0x9c, 0x08, 0x3d, 0x4f, 0xee, 0xbe, 0x31, 0x00, 0x93, 0xee, 0x49, 0xfd, 0xab, 0x3a, 0x04, 0x51,
0xce, 0x72, 0xe5, 0x6b, 0xc4, 0x8b, 0xcb, 0xd5, 0x36, 0x29, 0xd9, 0x73, 0x5a, 0xce, 0xc3, 0x54,
0x24, 0xd4, 0x42, 0x4d, 0x1e, 0x04, 0x2e, 0x35, 0x06, 0xd0, 0x4b, 0xf7, 0x0f, 0x02, 0x97, 0xfd,
0x58, 0x80, 0x85, 0x94, 0x1d, 0x1d, 0xe1, 0x0e, 0xcc, 0x75, 0xb8, 0xf4, 0xfc, 0x46, 0x4d, 0x83,
0x29, 0x13, 0x4b, 0xa7, 0x8f, 0xe2, 0xf9, 0x0d, 0x6d, 0xbb, 0x53, 0x28, 0x19, 0xd5, 0xd9, 0x4e,
0x62, 0x05, 0xef, 0xc2, 0x3c, 0x5d, 0x98, 0x88, 0x46, 0x9f, 0xf0, 0x62, 0x86, 0xe6, 0x8e, 0x06,
0x25, 0x78, 0xe6, 0xea, 0xc9, 0x25, 0xbc, 0x05, 0xb3, 0xd2, 0x69, 0x36, 0x0f, 0x22, 0x9a, 0x71,
0x45, 0x63, 0x66, 0x68, 0xee, 0x87, 0x90, 0x04, 0x49, 0x51, 0x76, 0x17, 0xf0, 0x0a, 0x4c, 0x91,
0xb1, 0xbe, 0xab, 0xe7, 0xb2, 0x37, 0x49, 0x07, 0x80, 0x40, 0xcc, 0xa7, 0xb8, 0x90, 0xb4, 0xa1,
0x4b, 0x2b, 0xd5, 0x4e, 0x0a, 0x43, 0xb7, 0x13, 0xf6, 0x1e, 0xf5, 0xe7, 0xd8, 0x1f, 0x25, 0xe2,
0x4d, 0x38, 0x43, 0x20, 0x4a, 0xc1, 0xf9, 0xfc, 0xd8, 0x55, 0x23, 0x18, 0xfb, 0x22, 0xcd, 0xf4,
0xdf, 0xdf, 0x8a, 0xa7, 0x06, 0xf5, 0xf8, 0xae, 0x02, 0x3a, 0xcc, 0x26, 0x4c, 0x93, 0xca, 0xe8,
0x6e, 0xf4, 0x3a, 0x4d, 0x8c, 0x7b, 0x71, 0x37, 0xe4, 0x2d, 0x58, 0x54, 0xaa, 0x54, 0x95, 0x54,
0x5d, 0xd1, 0x6e, 0xca, 0x11, 0x86, 0x60, 0xe9, 0xb4, 0x6d, 0x9c, 0xa1, 0x49, 0x55, 0x67, 0x94,
0x9f, 0xdc, 0xa2, 0x24, 0x13, 0x0d, 0x64, 0x3b, 0xb0, 0x9c, 0xea, 0xf8, 0x61, 0x43, 0xf8, 0x30,
0x50, 0xcf, 0x87, 0xa1, 0x15, 0x79, 0xb0, 0xd2, 0x9b, 0x83, 0x94, 0xbd, 0x0b, 0xe1, 0x75, 0x74,
0x6b, 0x5c, 0xaf, 0x93, 0x40, 0xd6, 0x63, 0x84, 0x24, 0x19, 0x8a, 0x9d, 0xee, 0xc7, 0xe6, 0x2f,
0x45, 0x98, 0x54, 0xbe, 0xf0, 0x2b, 0x03, 0x66, 0x93, 0x2f, 0x10, 0x5c, 0xcf, 0x70, 0xf5, 0x7a,
0xbf, 0x98, 0x1b, 0x83, 0x81, 0x5a, 0x34, 0x5b, 0x7d, 0xf2, 0xe7, 0x3f, 0x3f, 0x14, 0x2e, 0xe1,
0x92, 0x9d, 0x7e, 0x42, 0x25, 0x5f, 0x33, 0xf8, 0xa5, 0x01, 0xd3, 0x91, 0x6e, 0x5c, 0xcd, 0xe3,
0xce, 0xbc, 0x73, 0xcc, 0x57, 0xfa, 0x83, 0xc8, 0xb9, 0xa5, 0x9c, 0x6f, 0xe0, 0x5a, 0xc6, 0x79,
0x3c, 0x5c, 0xed, 0xc3, 0x44, 0x5a, 0x8e, 0xf0, 0x73, 0x98, 0x89, 0xc7, 0x36, 0xf6, 0x75, 0x11,
0x65, 0xd6, 0xbc, 0x3c, 0x00, 0x45, 0x4a, 0x56, 0x94, 0x12, 0x13, 0x4b, 0xbd, 0x94, 0xe0, 0xd7,
0x06, 0x4c, 0x84, 0x39, 0xc3, 0xe5, 0x3c, 0xc6, 0xc4, 0xcc, 0x36, 0x57, 0x7a, 0x03, 0xc8, 0xdb,
0x4d, 0xe5, 0xed, 0x1a, 0x5e, 0x1d, 0xee, 0xdc, 0xb6, 0x1a, 0x5e, 0xf6, 0xa1, 0x9a, 0xe0, 0x47,
0xf8, 0xc4, 0x80, 0x49, 0x35, 0x01, 0xb1, 0xa7, 0xa7, 0xf8, 0xf8, 0x2f, 0xf7, 0x41, 0x90, 0x98,
0xab, 0x4a, 0x8c, 0x85, 0x6f, 0x8c, 0x22, 0x06, 0x1f, 0xc3, 0x14, 0x75, 0xfa, 0x5c, 0x17, 0xa9,
0xb9, 0x68, 0xb2, 0x7e, 0x10, 0x92, 0xf1, 0xba, 0x92, 0x71, 0x19, 0x57, 0xb3, 0x32, 0x14, 0xcc,
0x3e, 0x4c, 0x0c, 0xd6, 0x23, 0xfc, 0xc9, 0x80, 0x33, 0xd4, 0xbb, 0x30, 0x97, 0x3c, 0x3d, 0x47,
0xcc, 0xd5, 0xbe, 0x18, 0x52, 0x70, 0x5b, 0x29, 0x78, 0x1b, 0x6f, 0x0c, 0x19, 0x88, 0xa8, 0x67,
0xda, 0x87, 0xf1, 0x5c, 0x39, 0xc2, 0x6f, 0x0d, 0x98, 0x8e, 0x1a, 0x31, 0xf6, 0x73, 0x2b, 0xfa,
0x5e, 0x95, 0x6c, 0x2f, 0x67, 0xd7, 0x95, 0xb8, 0x0a, 0xda, 0x23, 0x8a, 0xc3, 0xa7, 0x06, 0x14,
0x13, 0x4d, 0x11, 0xd7, 0xf2, 0xdc, 0x9d, 0x6e, 0xd2, 0xe6, 0xfa, 0x40, 0xdc, 0x73, 0xd6, 0x8f,
0x6a, 0xca, 0xf8, 0xab, 0x01, 0x0b, 0x39, 0xad, 0x10, 0xad, 0x7e, 0xf7, 0xf5, 0x74, 0xe7, 0x36,
0xed, 0xa1, 0xf1, 0x24, 0xf7, 0x86, 0x92, 0xbb, 0x8d, 0x5b, 0x23, 0x94, 0x7b, 0xd4, 0xd2, 0x77,
0xb6, 0x7f, 0x3f, 0x2e, 0x1b, 0xcf, 0x8e, 0xcb, 0xc6, 0xdf, 0xc7, 0x65, 0xe3, 0xfb, 0x93, 0xf2,
0xd8, 0xb3, 0x93, 0xf2, 0xd8, 0x5f, 0x27, 0xe5, 0xb1, 0x4f, 0x96, 0x34, 0x9b, 0xa8, 0x7f, 0x6a,
0x79, 0xdc, 0xfe, 0x4c, 0xb1, 0x86, 0xb5, 0x2a, 0xc2, 0x5f, 0xda, 0x29, 0xf5, 0xc7, 0xb9, 0xf5,
0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x41, 0xdd, 0x3f, 0x7e, 0x1b, 0x0f, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -1096,6 +1194,8 @@ type QueryClient interface {
Deposits(ctx context.Context, in *QueryDepositsRequest, opts ...grpc.CallOption) (*QueryDepositsResponse, error)
// TallyResult queries the tally of a proposal vote.
TallyResult(ctx context.Context, in *QueryTallyResultRequest, opts ...grpc.CallOption) (*QueryTallyResultResponse, error)
// ProposalVoteOptions queries the valid voting options for a proposal.
ProposalVoteOptions(ctx context.Context, in *QueryProposalVoteOptionsRequest, opts ...grpc.CallOption) (*QueryProposalVoteOptionsResponse, error)
}
type queryClient struct {
@ -1187,6 +1287,15 @@ func (c *queryClient) TallyResult(ctx context.Context, in *QueryTallyResultReque
return out, nil
}
func (c *queryClient) ProposalVoteOptions(ctx context.Context, in *QueryProposalVoteOptionsRequest, opts ...grpc.CallOption) (*QueryProposalVoteOptionsResponse, error) {
out := new(QueryProposalVoteOptionsResponse)
err := c.cc.Invoke(ctx, "/cosmos.gov.v1.Query/ProposalVoteOptions", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// Constitution queries the chain's constitution.
@ -1207,6 +1316,8 @@ type QueryServer interface {
Deposits(context.Context, *QueryDepositsRequest) (*QueryDepositsResponse, error)
// TallyResult queries the tally of a proposal vote.
TallyResult(context.Context, *QueryTallyResultRequest) (*QueryTallyResultResponse, error)
// ProposalVoteOptions queries the valid voting options for a proposal.
ProposalVoteOptions(context.Context, *QueryProposalVoteOptionsRequest) (*QueryProposalVoteOptionsResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
@ -1240,6 +1351,9 @@ func (*UnimplementedQueryServer) Deposits(ctx context.Context, req *QueryDeposit
func (*UnimplementedQueryServer) TallyResult(ctx context.Context, req *QueryTallyResultRequest) (*QueryTallyResultResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method TallyResult not implemented")
}
func (*UnimplementedQueryServer) ProposalVoteOptions(ctx context.Context, req *QueryProposalVoteOptionsRequest) (*QueryProposalVoteOptionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ProposalVoteOptions not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
@ -1407,6 +1521,24 @@ func _Query_TallyResult_Handler(srv interface{}, ctx context.Context, dec func(i
return interceptor(ctx, in, info, handler)
}
func _Query_ProposalVoteOptions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryProposalVoteOptionsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).ProposalVoteOptions(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.gov.v1.Query/ProposalVoteOptions",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).ProposalVoteOptions(ctx, req.(*QueryProposalVoteOptionsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.gov.v1.Query",
HandlerType: (*QueryServer)(nil),
@ -1447,6 +1579,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{
MethodName: "TallyResult",
Handler: _Query_TallyResult_Handler,
},
{
MethodName: "ProposalVoteOptions",
Handler: _Query_ProposalVoteOptions_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/gov/v1/query.proto",
@ -2153,6 +2289,69 @@ func (m *QueryTallyResultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error
return len(dAtA) - i, nil
}
func (m *QueryProposalVoteOptionsRequest) 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 *QueryProposalVoteOptionsRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryProposalVoteOptionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.ProposalId != 0 {
i = encodeVarintQuery(dAtA, i, uint64(m.ProposalId))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *QueryProposalVoteOptionsResponse) 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 *QueryProposalVoteOptionsResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryProposalVoteOptionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.VoteOptions != nil {
{
size, err := m.VoteOptions.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
@ -2445,6 +2644,31 @@ func (m *QueryTallyResultResponse) Size() (n int) {
return n
}
func (m *QueryProposalVoteOptionsRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ProposalId != 0 {
n += 1 + sovQuery(uint64(m.ProposalId))
}
return n
}
func (m *QueryProposalVoteOptionsResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.VoteOptions != nil {
l = m.VoteOptions.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -4282,6 +4506,161 @@ func (m *QueryTallyResultResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *QueryProposalVoteOptionsRequest) 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 ErrIntOverflowQuery
}
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: QueryProposalVoteOptionsRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryProposalVoteOptionsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ProposalId", wireType)
}
m.ProposalId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ProposalId |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryProposalVoteOptionsResponse) 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 ErrIntOverflowQuery
}
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: QueryProposalVoteOptionsResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryProposalVoteOptionsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteOptions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.VoteOptions == nil {
m.VoteOptions = &ProposalVoteOptions{}
}
if err := m.VoteOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -545,6 +545,60 @@ func local_request_Query_TallyResult_0(ctx context.Context, marshaler runtime.Ma
}
func request_Query_ProposalVoteOptions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryProposalVoteOptionsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["proposal_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "proposal_id")
}
protoReq.ProposalId, err = runtime.Uint64(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "proposal_id", err)
}
msg, err := client.ProposalVoteOptions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_ProposalVoteOptions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryProposalVoteOptionsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["proposal_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "proposal_id")
}
protoReq.ProposalId, err = runtime.Uint64(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "proposal_id", err)
}
msg, err := server.ProposalVoteOptions(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@ -758,6 +812,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
})
mux.Handle("GET", pattern_Query_ProposalVoteOptions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_ProposalVoteOptions_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_ProposalVoteOptions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -979,6 +1056,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
})
mux.Handle("GET", pattern_Query_ProposalVoteOptions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_ProposalVoteOptions_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_ProposalVoteOptions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -1000,6 +1097,8 @@ var (
pattern_Query_Deposits_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"cosmos", "gov", "v1", "proposals", "proposal_id", "deposits"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_TallyResult_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"cosmos", "gov", "v1", "proposals", "proposal_id", "tally"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_ProposalVoteOptions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"cosmos", "gov", "v1", "proposals", "proposal_id", "vote_options"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
@ -1020,4 +1119,6 @@ var (
forward_Query_Deposits_0 = runtime.ForwardResponseMessage
forward_Query_TallyResult_0 = runtime.ForwardResponseMessage
forward_Query_ProposalVoteOptions_0 = runtime.ForwardResponseMessage
)

View File

@ -67,7 +67,7 @@ type MsgSubmitProposal struct {
// proposal_type defines the type of proposal
// When not set defaults to PROPOSAL_TYPE_STANDARD
//
// Since: cosmos-sdk 0.51
// Since: x/gov v1.0.0
ProposalType ProposalType `protobuf:"varint,8,opt,name=proposal_type,json=proposalType,proto3,enum=cosmos.gov.v1.ProposalType" json:"proposal_type,omitempty"`
}
@ -844,6 +844,149 @@ func (m *MsgCancelProposalResponse) GetCanceledHeight() uint64 {
return 0
}
// MsgSubmitMultipleChoiceProposal defines a message to submit a multiple choice proposal.
//
// Since: x/gov 1.0.0
type MsgSubmitMultipleChoiceProposal struct {
// initial_deposit is the deposit value that must be paid at proposal submission.
InitialDeposit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=initial_deposit,json=initialDeposit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"initial_deposit"`
// proposer is the account address of the proposer.
Proposer string `protobuf:"bytes,2,opt,name=proposer,proto3" json:"proposer,omitempty"`
// metadata is any arbitrary metadata attached to the proposal.
Metadata string `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"`
// title is the title of the proposal.
Title string `protobuf:"bytes,4,opt,name=title,proto3" json:"title,omitempty"`
// summary is the summary of the proposal
Summary string `protobuf:"bytes,5,opt,name=summary,proto3" json:"summary,omitempty"`
// vote_options defines the vote options for the proposal.
VoteOptions *ProposalVoteOptions `protobuf:"bytes,6,opt,name=vote_options,json=voteOptions,proto3" json:"vote_options,omitempty"`
}
func (m *MsgSubmitMultipleChoiceProposal) Reset() { *m = MsgSubmitMultipleChoiceProposal{} }
func (m *MsgSubmitMultipleChoiceProposal) String() string { return proto.CompactTextString(m) }
func (*MsgSubmitMultipleChoiceProposal) ProtoMessage() {}
func (*MsgSubmitMultipleChoiceProposal) Descriptor() ([]byte, []int) {
return fileDescriptor_9ff8f4a63b6fc9a9, []int{14}
}
func (m *MsgSubmitMultipleChoiceProposal) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *MsgSubmitMultipleChoiceProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_MsgSubmitMultipleChoiceProposal.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 *MsgSubmitMultipleChoiceProposal) XXX_Merge(src proto.Message) {
xxx_messageInfo_MsgSubmitMultipleChoiceProposal.Merge(m, src)
}
func (m *MsgSubmitMultipleChoiceProposal) XXX_Size() int {
return m.Size()
}
func (m *MsgSubmitMultipleChoiceProposal) XXX_DiscardUnknown() {
xxx_messageInfo_MsgSubmitMultipleChoiceProposal.DiscardUnknown(m)
}
var xxx_messageInfo_MsgSubmitMultipleChoiceProposal proto.InternalMessageInfo
func (m *MsgSubmitMultipleChoiceProposal) GetInitialDeposit() github_com_cosmos_cosmos_sdk_types.Coins {
if m != nil {
return m.InitialDeposit
}
return nil
}
func (m *MsgSubmitMultipleChoiceProposal) GetProposer() string {
if m != nil {
return m.Proposer
}
return ""
}
func (m *MsgSubmitMultipleChoiceProposal) GetMetadata() string {
if m != nil {
return m.Metadata
}
return ""
}
func (m *MsgSubmitMultipleChoiceProposal) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *MsgSubmitMultipleChoiceProposal) GetSummary() string {
if m != nil {
return m.Summary
}
return ""
}
func (m *MsgSubmitMultipleChoiceProposal) GetVoteOptions() *ProposalVoteOptions {
if m != nil {
return m.VoteOptions
}
return nil
}
// MsgSubmitMultipleChoiceProposalResponse defines the Msg/SubmitMultipleChoiceProposal response type.
//
// Since: x/gov 1.0.0
type MsgSubmitMultipleChoiceProposalResponse struct {
// proposal_id defines the unique id of the proposal.
ProposalId uint64 `protobuf:"varint,1,opt,name=proposal_id,json=proposalId,proto3" json:"proposal_id,omitempty"`
}
func (m *MsgSubmitMultipleChoiceProposalResponse) Reset() {
*m = MsgSubmitMultipleChoiceProposalResponse{}
}
func (m *MsgSubmitMultipleChoiceProposalResponse) String() string { return proto.CompactTextString(m) }
func (*MsgSubmitMultipleChoiceProposalResponse) ProtoMessage() {}
func (*MsgSubmitMultipleChoiceProposalResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_9ff8f4a63b6fc9a9, []int{15}
}
func (m *MsgSubmitMultipleChoiceProposalResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *MsgSubmitMultipleChoiceProposalResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_MsgSubmitMultipleChoiceProposalResponse.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 *MsgSubmitMultipleChoiceProposalResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_MsgSubmitMultipleChoiceProposalResponse.Merge(m, src)
}
func (m *MsgSubmitMultipleChoiceProposalResponse) XXX_Size() int {
return m.Size()
}
func (m *MsgSubmitMultipleChoiceProposalResponse) XXX_DiscardUnknown() {
xxx_messageInfo_MsgSubmitMultipleChoiceProposalResponse.DiscardUnknown(m)
}
var xxx_messageInfo_MsgSubmitMultipleChoiceProposalResponse proto.InternalMessageInfo
func (m *MsgSubmitMultipleChoiceProposalResponse) GetProposalId() uint64 {
if m != nil {
return m.ProposalId
}
return 0
}
func init() {
proto.RegisterType((*MsgSubmitProposal)(nil), "cosmos.gov.v1.MsgSubmitProposal")
proto.RegisterType((*MsgSubmitProposalResponse)(nil), "cosmos.gov.v1.MsgSubmitProposalResponse")
@ -859,82 +1002,90 @@ func init() {
proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.gov.v1.MsgUpdateParamsResponse")
proto.RegisterType((*MsgCancelProposal)(nil), "cosmos.gov.v1.MsgCancelProposal")
proto.RegisterType((*MsgCancelProposalResponse)(nil), "cosmos.gov.v1.MsgCancelProposalResponse")
proto.RegisterType((*MsgSubmitMultipleChoiceProposal)(nil), "cosmos.gov.v1.MsgSubmitMultipleChoiceProposal")
proto.RegisterType((*MsgSubmitMultipleChoiceProposalResponse)(nil), "cosmos.gov.v1.MsgSubmitMultipleChoiceProposalResponse")
}
func init() { proto.RegisterFile("cosmos/gov/v1/tx.proto", fileDescriptor_9ff8f4a63b6fc9a9) }
var fileDescriptor_9ff8f4a63b6fc9a9 = []byte{
// 1114 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcb, 0x6f, 0xdc, 0x44,
0x18, 0xcf, 0xe4, 0xb5, 0xc9, 0xe4, 0xa5, 0x8c, 0xb6, 0xad, 0xe3, 0x16, 0xef, 0xd6, 0x45, 0xb0,
0x4a, 0x89, 0xcd, 0x06, 0x52, 0xa1, 0xa5, 0x42, 0x74, 0xc3, 0xab, 0x12, 0x81, 0xca, 0x2d, 0x45,
0x42, 0x48, 0x91, 0xb3, 0x1e, 0x1c, 0xab, 0x6b, 0x8f, 0xb5, 0x33, 0xbb, 0xca, 0xde, 0x10, 0xc7,
0x9c, 0x7a, 0xe6, 0x2f, 0x40, 0x9c, 0x72, 0xe8, 0xad, 0x27, 0x6e, 0x15, 0xa7, 0x8a, 0x13, 0xa7,
0x16, 0x25, 0x82, 0x20, 0xf8, 0x23, 0x40, 0x33, 0x1e, 0x7b, 0xfd, 0xca, 0xa6, 0x70, 0xe8, 0x65,
0xd7, 0xf3, 0xbd, 0xe6, 0xfb, 0xfd, 0xbe, 0x6f, 0xbe, 0x19, 0x78, 0xb1, 0x43, 0xa8, 0x4f, 0xa8,
0xe9, 0x92, 0x81, 0x39, 0x68, 0x9a, 0xec, 0xc0, 0x08, 0x7b, 0x84, 0x11, 0xb4, 0x14, 0xc9, 0x0d,
0x97, 0x0c, 0x8c, 0x41, 0x53, 0xd5, 0xa4, 0xd9, 0x9e, 0x4d, 0xb1, 0x39, 0x68, 0xee, 0x61, 0x66,
0x37, 0xcd, 0x0e, 0xf1, 0x82, 0xc8, 0x5c, 0xbd, 0x94, 0x0d, 0xc3, 0xbd, 0x22, 0x45, 0xd5, 0x25,
0x2e, 0x11, 0x9f, 0x26, 0xff, 0x92, 0xd2, 0xb5, 0xc8, 0x7c, 0x37, 0x52, 0xc8, 0xad, 0xa4, 0xca,
0x25, 0xc4, 0xed, 0x62, 0x53, 0xac, 0xf6, 0xfa, 0xdf, 0x98, 0x76, 0x30, 0xcc, 0x6d, 0xe2, 0x53,
0x97, 0x6f, 0xe2, 0x53, 0x57, 0x2a, 0x56, 0x6d, 0xdf, 0x0b, 0x88, 0x29, 0x7e, 0xa5, 0xa8, 0x96,
0x0f, 0xc3, 0x3c, 0x1f, 0x53, 0x66, 0xfb, 0x61, 0x64, 0xa0, 0xff, 0x3d, 0x05, 0x57, 0x77, 0xa8,
0x7b, 0xb7, 0xbf, 0xe7, 0x7b, 0xec, 0x4e, 0x8f, 0x84, 0x84, 0xda, 0x5d, 0xf4, 0x26, 0x9c, 0xf3,
0x31, 0xa5, 0xb6, 0x8b, 0xa9, 0x02, 0xea, 0x53, 0x8d, 0x85, 0xcd, 0xaa, 0x11, 0x45, 0x32, 0xe2,
0x48, 0xc6, 0xad, 0x60, 0x68, 0x25, 0x56, 0xe8, 0x10, 0xc0, 0x15, 0x2f, 0xf0, 0x98, 0x67, 0x77,
0x77, 0x1d, 0x1c, 0x12, 0xea, 0x31, 0x65, 0x52, 0x78, 0xae, 0x19, 0x12, 0x18, 0x27, 0xcd, 0x90,
0xa4, 0x19, 0xdb, 0xc4, 0x0b, 0xda, 0x1f, 0x3d, 0x79, 0x56, 0x9b, 0xf8, 0xf1, 0x79, 0xad, 0xe1,
0x7a, 0x6c, 0xbf, 0xbf, 0x67, 0x74, 0x88, 0x2f, 0x59, 0x90, 0x7f, 0x1b, 0xd4, 0x79, 0x60, 0xb2,
0x61, 0x88, 0xa9, 0x70, 0xa0, 0xdf, 0x9f, 0x1e, 0xad, 0x2f, 0x76, 0xb1, 0x6b, 0x77, 0x86, 0xbb,
0x9c, 0x76, 0xfa, 0xc3, 0xe9, 0xd1, 0x3a, 0xb0, 0x96, 0xe5, 0xce, 0x1f, 0x44, 0x1b, 0xa3, 0xb7,
0xe1, 0x5c, 0x28, 0xa0, 0xe0, 0x9e, 0x32, 0x55, 0x07, 0x8d, 0xf9, 0xb6, 0xf2, 0xcb, 0xa3, 0x8d,
0xaa, 0xcc, 0xe3, 0x96, 0xe3, 0xf4, 0x30, 0xa5, 0x77, 0x59, 0xcf, 0x0b, 0x5c, 0x2b, 0xb1, 0x44,
0x2a, 0x07, 0xcd, 0x6c, 0xc7, 0x66, 0xb6, 0x32, 0xcd, 0xbd, 0xac, 0x64, 0x8d, 0xaa, 0x70, 0x86,
0x79, 0xac, 0x8b, 0x95, 0x19, 0xa1, 0x88, 0x16, 0x48, 0x81, 0x15, 0xda, 0xf7, 0x7d, 0xbb, 0x37,
0x54, 0x66, 0x85, 0x3c, 0x5e, 0xa2, 0x3a, 0x9c, 0xc7, 0x07, 0x21, 0x76, 0x3c, 0x86, 0x1d, 0xa5,
0x52, 0x07, 0x8d, 0xb9, 0xf6, 0xa4, 0x02, 0xac, 0x91, 0x10, 0xbd, 0x0f, 0x97, 0x42, 0x49, 0xf7,
0x2e, 0x47, 0xa8, 0xcc, 0xd5, 0x41, 0x63, 0x79, 0xf3, 0xb2, 0x91, 0xe9, 0x38, 0x23, 0x2e, 0xc9,
0xbd, 0x61, 0x88, 0xad, 0xc5, 0x30, 0xb5, 0x6a, 0x35, 0xbf, 0x3b, 0x3d, 0x5a, 0x4f, 0xd2, 0x3f,
0x3c, 0x3d, 0x5a, 0xaf, 0xa5, 0x58, 0x1b, 0x34, 0xcd, 0x42, 0x5d, 0xf5, 0x9b, 0x70, 0xad, 0x20,
0xb4, 0x30, 0x0d, 0x49, 0x40, 0x31, 0xaa, 0xc1, 0x85, 0x24, 0x23, 0xcf, 0x51, 0x40, 0x1d, 0x34,
0xa6, 0x2d, 0x18, 0x8b, 0x6e, 0x3b, 0xfa, 0x63, 0x00, 0xab, 0x3b, 0xd4, 0xfd, 0xf0, 0x00, 0x77,
0x3e, 0x15, 0x35, 0xd8, 0x26, 0x01, 0xc3, 0x01, 0x43, 0x9f, 0xc1, 0x4a, 0x27, 0xfa, 0x14, 0x5e,
0x67, 0x74, 0x4b, 0x5b, 0xfb, 0xf9, 0xd1, 0x86, 0x9a, 0x81, 0x17, 0xf7, 0x82, 0xf0, 0xb5, 0xe2,
0x20, 0xe8, 0x0a, 0x9c, 0xb7, 0xfb, 0x6c, 0x9f, 0xf4, 0x3c, 0x36, 0x54, 0x26, 0x05, 0xb3, 0x23,
0x41, 0x6b, 0x8b, 0xe3, 0x1e, 0xad, 0x39, 0x70, 0xbd, 0x00, 0xbc, 0x90, 0xa4, 0xae, 0xc1, 0x2b,
0x65, 0xf2, 0x18, 0xbe, 0xfe, 0x3b, 0x80, 0x95, 0x1d, 0xea, 0xde, 0x27, 0x0c, 0xa3, 0xad, 0x12,
0x2a, 0xda, 0xd5, 0xbf, 0x9e, 0xd5, 0xd2, 0xe2, 0xa8, 0xf7, 0x52, 0x04, 0x21, 0x03, 0xce, 0x0c,
0x08, 0xc3, 0xbd, 0x28, 0xe7, 0x31, 0x4d, 0x17, 0x99, 0xa1, 0x26, 0x9c, 0x25, 0x21, 0xf3, 0x48,
0x20, 0xba, 0x74, 0x79, 0x74, 0x54, 0x64, 0xf1, 0x79, 0x2e, 0x9f, 0x0b, 0x03, 0x4b, 0x1a, 0x8e,
0x6b, 0xd2, 0xd6, 0xab, 0x9c, 0x98, 0x28, 0x34, 0x27, 0xe5, 0x42, 0x81, 0x14, 0x1e, 0x4f, 0x5f,
0x85, 0x2b, 0xf2, 0x33, 0x81, 0xfe, 0x0f, 0x48, 0x64, 0x5f, 0x62, 0xcf, 0xdd, 0xe7, 0xfd, 0xf9,
0x92, 0x28, 0x78, 0x17, 0x56, 0x22, 0x64, 0x54, 0x99, 0x12, 0xe3, 0xe2, 0x6a, 0x8e, 0x83, 0x38,
0xa1, 0x14, 0x17, 0xb1, 0xc7, 0x58, 0x32, 0xde, 0xc8, 0x92, 0xf1, 0x4a, 0x29, 0x19, 0x71, 0x70,
0x7d, 0x0d, 0x5e, 0xca, 0x89, 0x12, 0x72, 0xfe, 0x00, 0x10, 0xee, 0x50, 0x37, 0x9e, 0x2d, 0xff,
0x93, 0x97, 0x1b, 0x70, 0x5e, 0x8e, 0x45, 0x72, 0x3e, 0x37, 0x23, 0x53, 0x74, 0x13, 0xce, 0xda,
0x3e, 0xe9, 0x07, 0x4c, 0xd2, 0x33, 0x66, 0x9a, 0xce, 0xf3, 0x69, 0x1a, 0xed, 0x2c, 0x7d, 0x5a,
0xd7, 0xc5, 0x51, 0x49, 0xa2, 0x71, 0x22, 0x94, 0x02, 0x11, 0x12, 0x99, 0x5e, 0x85, 0x68, 0xb4,
0x4a, 0xe0, 0x3f, 0x8e, 0x7a, 0xe3, 0x8b, 0xd0, 0xb1, 0x19, 0xbe, 0x63, 0xf7, 0x6c, 0x9f, 0x72,
0x30, 0xa3, 0xf3, 0x09, 0xce, 0x03, 0x93, 0x98, 0xa2, 0x77, 0xe0, 0x6c, 0x28, 0x22, 0x08, 0x06,
0x16, 0x36, 0x2f, 0xe4, 0x87, 0x9d, 0x50, 0x66, 0x80, 0x44, 0xf6, 0xad, 0x1b, 0xc5, 0x33, 0x7f,
0x2d, 0x05, 0xe4, 0x20, 0xbe, 0x71, 0x73, 0x99, 0xca, 0xba, 0xa6, 0x45, 0x09, 0xb0, 0x43, 0x20,
0x6e, 0xbe, 0x6d, 0x3b, 0xe8, 0xe0, 0x6e, 0xea, 0xe6, 0x2b, 0x29, 0xef, 0x4a, 0xae, 0xbc, 0x99,
0xca, 0xa6, 0x2f, 0x9b, 0xc9, 0x17, 0xbd, 0x6c, 0x5a, 0x4b, 0x99, 0xe1, 0xad, 0xff, 0x04, 0xc4,
0x64, 0xce, 0x26, 0x93, 0x4c, 0xe6, 0xff, 0x9e, 0xd4, 0x6d, 0xb8, 0xd4, 0x11, 0xb1, 0xb0, 0xb3,
0xcb, 0xaf, 0x7c, 0x49, 0xb8, 0x5a, 0x98, 0xcb, 0xf7, 0xe2, 0xf7, 0x40, 0x7b, 0x8e, 0xb3, 0xfe,
0xf0, 0x79, 0x0d, 0x58, 0x8b, 0xb1, 0x2b, 0x57, 0xa2, 0xd7, 0xe1, 0x4a, 0x12, 0x6a, 0x5f, 0x1c,
0x0e, 0x31, 0xad, 0xa6, 0xad, 0xe5, 0x58, 0xfc, 0x89, 0x90, 0x6e, 0xfe, 0x39, 0x0d, 0xa7, 0x76,
0xa8, 0x8b, 0xbe, 0x86, 0xcb, 0xb9, 0xe7, 0x44, 0x3d, 0x57, 0xe7, 0xc2, 0x1d, 0xa4, 0x36, 0xce,
0xb3, 0x48, 0xb8, 0xc0, 0x70, 0xb5, 0x78, 0x01, 0x5d, 0x2b, 0xba, 0x17, 0x8c, 0xd4, 0xeb, 0x2f,
0x60, 0x94, 0x6c, 0xf3, 0x1e, 0x9c, 0x16, 0x37, 0xc1, 0xc5, 0xa2, 0x13, 0x97, 0xab, 0x5a, 0xb9,
0x3c, 0xf1, 0xbf, 0x0f, 0x17, 0x33, 0xe3, 0xf4, 0x0c, 0xfb, 0x58, 0xaf, 0xbe, 0x36, 0x5e, 0x9f,
0xc4, 0xfd, 0x18, 0x56, 0xe2, 0x49, 0xb4, 0x56, 0x74, 0x91, 0x2a, 0xf5, 0xea, 0x99, 0xaa, 0x74,
0x82, 0x99, 0x33, 0x5d, 0x92, 0x60, 0x5a, 0x5f, 0x96, 0x60, 0xd9, 0xb1, 0xe2, 0xd5, 0xcf, 0x1d,
0xa9, 0x92, 0xea, 0x67, 0x2d, 0xca, 0xaa, 0x5f, 0x7e, 0x12, 0xd4, 0x99, 0x6f, 0xf9, 0x58, 0x68,
0x6f, 0x3d, 0x39, 0xd6, 0xc0, 0xd3, 0x63, 0x0d, 0xfc, 0x76, 0xac, 0x81, 0x87, 0x27, 0xda, 0xc4,
0xd3, 0x13, 0x6d, 0xe2, 0xd7, 0x13, 0x6d, 0xe2, 0xab, 0xcb, 0x51, 0x24, 0xea, 0x3c, 0x30, 0x3c,
0x22, 0xe7, 0x82, 0x78, 0x40, 0xf2, 0xe7, 0xfa, 0xac, 0x68, 0xfb, 0xb7, 0xfe, 0x0d, 0x00, 0x00,
0xff, 0xff, 0x46, 0x1f, 0x89, 0xe5, 0xee, 0x0b, 0x00, 0x00,
// 1216 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5,
0x17, 0xcf, 0xc4, 0xb1, 0x9d, 0x4c, 0x7e, 0x29, 0x2b, 0xb7, 0xdd, 0x6c, 0xfb, 0xb5, 0xdd, 0xed,
0x57, 0xd4, 0x4a, 0xe9, 0x1a, 0x07, 0x12, 0x21, 0x53, 0x21, 0xea, 0x50, 0xa0, 0x08, 0x43, 0xb5,
0x2d, 0x45, 0x42, 0x48, 0xd6, 0xc6, 0x3b, 0x6c, 0x56, 0xf5, 0xee, 0xac, 0x3c, 0x63, 0x2b, 0xbe,
0x21, 0x0e, 0x3d, 0xe4, 0xd4, 0x33, 0x7f, 0x01, 0xe2, 0x94, 0x43, 0x6f, 0x3d, 0x71, 0xab, 0x38,
0x55, 0x9c, 0x38, 0xb5, 0x28, 0x11, 0x44, 0x82, 0x13, 0x7f, 0x01, 0x68, 0x66, 0x67, 0xd7, 0xfb,
0xcb, 0x4e, 0xda, 0x03, 0xe2, 0x92, 0xec, 0xbc, 0x5f, 0xf3, 0xde, 0xe7, 0xbd, 0xf9, 0xcc, 0x18,
0x9e, 0xef, 0x62, 0xe2, 0x60, 0x52, 0xb7, 0xf0, 0xb0, 0x3e, 0x6c, 0xd4, 0xe9, 0xbe, 0xe6, 0xf5,
0x31, 0xc5, 0xd2, 0xb2, 0x2f, 0xd7, 0x2c, 0x3c, 0xd4, 0x86, 0x0d, 0xa5, 0x2c, 0xcc, 0x76, 0x0d,
0x82, 0xea, 0xc3, 0xc6, 0x2e, 0xa2, 0x46, 0xa3, 0xde, 0xc5, 0xb6, 0xeb, 0x9b, 0x2b, 0x17, 0xe2,
0x61, 0x98, 0x97, 0xaf, 0x28, 0x59, 0xd8, 0xc2, 0xfc, 0xb3, 0xce, 0xbe, 0x84, 0x74, 0xdd, 0x37,
0xef, 0xf8, 0x0a, 0xb1, 0x95, 0x50, 0x59, 0x18, 0x5b, 0x3d, 0x54, 0xe7, 0xab, 0xdd, 0xc1, 0xd7,
0x75, 0xc3, 0x1d, 0x25, 0x36, 0x71, 0x88, 0xc5, 0x36, 0x71, 0x88, 0x25, 0x14, 0x6b, 0x86, 0x63,
0xbb, 0xb8, 0xce, 0xff, 0x0a, 0x51, 0x25, 0x19, 0x86, 0xda, 0x0e, 0x22, 0xd4, 0x70, 0x3c, 0xdf,
0x40, 0xfd, 0x33, 0x07, 0xd7, 0xda, 0xc4, 0xba, 0x3b, 0xd8, 0x75, 0x6c, 0x7a, 0xa7, 0x8f, 0x3d,
0x4c, 0x8c, 0x9e, 0xf4, 0x06, 0x9c, 0x77, 0x10, 0x21, 0x86, 0x85, 0x88, 0x0c, 0xaa, 0xb9, 0xda,
0xe2, 0x66, 0x49, 0xf3, 0x23, 0x69, 0x41, 0x24, 0xed, 0xa6, 0x3b, 0xd2, 0x43, 0x2b, 0xe9, 0x00,
0xc0, 0x55, 0xdb, 0xb5, 0xa9, 0x6d, 0xf4, 0x3a, 0x26, 0xf2, 0x30, 0xb1, 0xa9, 0x3c, 0xcb, 0x3d,
0xd7, 0x35, 0x51, 0x18, 0x03, 0x4d, 0x13, 0xa0, 0x69, 0x3b, 0xd8, 0x76, 0x5b, 0x1f, 0x3c, 0x7d,
0x5e, 0x99, 0xf9, 0xe1, 0x45, 0xa5, 0x66, 0xd9, 0x74, 0x6f, 0xb0, 0xab, 0x75, 0xb1, 0x23, 0x50,
0x10, 0xff, 0xae, 0x13, 0xf3, 0x41, 0x9d, 0x8e, 0x3c, 0x44, 0xb8, 0x03, 0xf9, 0xee, 0xe4, 0x70,
0x63, 0xa9, 0x87, 0x2c, 0xa3, 0x3b, 0xea, 0x30, 0xd8, 0xc9, 0xf7, 0x27, 0x87, 0x1b, 0x40, 0x5f,
0x11, 0x3b, 0xbf, 0xef, 0x6f, 0x2c, 0xbd, 0x05, 0xe7, 0x3d, 0x5e, 0x0a, 0xea, 0xcb, 0xb9, 0x2a,
0xa8, 0x2d, 0xb4, 0xe4, 0x9f, 0x1f, 0x5f, 0x2f, 0x89, 0x3c, 0x6e, 0x9a, 0x66, 0x1f, 0x11, 0x72,
0x97, 0xf6, 0x6d, 0xd7, 0xd2, 0x43, 0x4b, 0x49, 0x61, 0x45, 0x53, 0xc3, 0x34, 0xa8, 0x21, 0xcf,
0x31, 0x2f, 0x3d, 0x5c, 0x4b, 0x25, 0x98, 0xa7, 0x36, 0xed, 0x21, 0x39, 0xcf, 0x15, 0xfe, 0x42,
0x92, 0x61, 0x91, 0x0c, 0x1c, 0xc7, 0xe8, 0x8f, 0xe4, 0x02, 0x97, 0x07, 0x4b, 0xa9, 0x0a, 0x17,
0xd0, 0xbe, 0x87, 0x4c, 0x9b, 0x22, 0x53, 0x2e, 0x56, 0x41, 0x6d, 0xbe, 0x35, 0x2b, 0x03, 0x7d,
0x2c, 0x94, 0xde, 0x83, 0xcb, 0x9e, 0x80, 0xbb, 0xc3, 0x2a, 0x94, 0xe7, 0xab, 0xa0, 0xb6, 0xb2,
0x79, 0x51, 0x8b, 0x4d, 0x9c, 0x16, 0xb4, 0xe4, 0xde, 0xc8, 0x43, 0xfa, 0x92, 0x17, 0x59, 0x35,
0x1b, 0xdf, 0x9e, 0x1c, 0x6e, 0x84, 0xe9, 0x1f, 0x9c, 0x1c, 0x6e, 0x54, 0x22, 0xa8, 0x0d, 0x1b,
0xf5, 0x54, 0x5f, 0xd5, 0x1b, 0x70, 0x3d, 0x25, 0xd4, 0x11, 0xf1, 0xb0, 0x4b, 0x90, 0x54, 0x81,
0x8b, 0x61, 0x46, 0xb6, 0x29, 0x83, 0x2a, 0xa8, 0xcd, 0xe9, 0x30, 0x10, 0xdd, 0x36, 0xd5, 0x27,
0x00, 0x96, 0xda, 0xc4, 0xba, 0xb5, 0x8f, 0xba, 0x9f, 0xf0, 0x1e, 0xec, 0x60, 0x97, 0x22, 0x97,
0x4a, 0x9f, 0xc2, 0x62, 0xd7, 0xff, 0xe4, 0x5e, 0x13, 0xa6, 0xa5, 0x55, 0xfe, 0xe9, 0xf1, 0x75,
0x25, 0x56, 0x5e, 0x30, 0x0b, 0xdc, 0x57, 0x0f, 0x82, 0x48, 0x97, 0xe0, 0x82, 0x31, 0xa0, 0x7b,
0xb8, 0x6f, 0xd3, 0x91, 0x3c, 0xcb, 0x91, 0x1d, 0x0b, 0x9a, 0x5b, 0xac, 0xee, 0xf1, 0x9a, 0x15,
0xae, 0xa6, 0x0a, 0x4f, 0x25, 0xa9, 0x96, 0xe1, 0xa5, 0x2c, 0x79, 0x50, 0xbe, 0xfa, 0x1b, 0x80,
0xc5, 0x36, 0xb1, 0xee, 0x63, 0x8a, 0xa4, 0xad, 0x0c, 0x28, 0x5a, 0xa5, 0x3f, 0x9e, 0x57, 0xa2,
0x62, 0x7f, 0xf6, 0x22, 0x00, 0x49, 0x1a, 0xcc, 0x0f, 0x31, 0x45, 0x7d, 0x3f, 0xe7, 0x29, 0x43,
0xe7, 0x9b, 0x49, 0x0d, 0x58, 0xc0, 0x1e, 0xb5, 0xb1, 0xcb, 0xa7, 0x74, 0x65, 0x7c, 0x54, 0x44,
0xf3, 0x59, 0x2e, 0x9f, 0x71, 0x03, 0x5d, 0x18, 0x4e, 0x1b, 0xd2, 0xe6, 0xff, 0x19, 0x30, 0x7e,
0x68, 0x06, 0xca, 0xb9, 0x14, 0x28, 0x2c, 0x9e, 0xba, 0x06, 0x57, 0xc5, 0x67, 0x58, 0xfa, 0xdf,
0x20, 0x94, 0x7d, 0x81, 0x6c, 0x6b, 0x8f, 0xcd, 0xe7, 0xbf, 0x04, 0xc1, 0x3b, 0xb0, 0xe8, 0x57,
0x46, 0xe4, 0x1c, 0xa7, 0x8b, 0xcb, 0x09, 0x0c, 0x82, 0x84, 0x22, 0x58, 0x04, 0x1e, 0x53, 0xc1,
0x78, 0x3d, 0x0e, 0xc6, 0xff, 0x32, 0xc1, 0x08, 0x82, 0xab, 0xeb, 0xf0, 0x42, 0x42, 0x14, 0x82,
0xf3, 0x3b, 0x80, 0xb0, 0x4d, 0xac, 0x80, 0x5b, 0x5e, 0x11, 0x97, 0x6d, 0xb8, 0x20, 0x68, 0x11,
0x9f, 0x8e, 0xcd, 0xd8, 0x54, 0xba, 0x01, 0x0b, 0x86, 0x83, 0x07, 0x2e, 0x15, 0xf0, 0x4c, 0x61,
0xd3, 0x05, 0xc6, 0xa6, 0xfe, 0xce, 0xc2, 0xa7, 0x79, 0x8d, 0x1f, 0x95, 0x30, 0x1a, 0x03, 0x42,
0x4e, 0x01, 0x21, 0x2a, 0x53, 0x4b, 0x50, 0x1a, 0xaf, 0xc2, 0xf2, 0x9f, 0xf8, 0xb3, 0xf1, 0xb9,
0x67, 0x1a, 0x14, 0xdd, 0x31, 0xfa, 0x86, 0x43, 0x58, 0x31, 0xe3, 0xf3, 0x09, 0x4e, 0x2b, 0x26,
0x34, 0x95, 0xde, 0x86, 0x05, 0x8f, 0x47, 0xe0, 0x08, 0x2c, 0x6e, 0x9e, 0x4b, 0x92, 0x1d, 0x57,
0xc6, 0x0a, 0xf1, 0xed, 0x9b, 0xdb, 0xe9, 0x33, 0x7f, 0x25, 0x52, 0xc8, 0x7e, 0x70, 0xe3, 0x26,
0x32, 0x15, 0x7d, 0x8d, 0x8a, 0xc2, 0xc2, 0x0e, 0x00, 0xbf, 0xf9, 0x76, 0x0c, 0xb7, 0x8b, 0x7a,
0x91, 0x9b, 0x2f, 0xa3, 0xbd, 0xab, 0x89, 0xf6, 0xc6, 0x3a, 0x1b, 0xbd, 0x6c, 0x66, 0xcf, 0x7a,
0xd9, 0x34, 0x97, 0x63, 0xe4, 0xad, 0xfe, 0x08, 0x38, 0x33, 0xc7, 0x93, 0x09, 0x99, 0xf9, 0xe5,
0x93, 0xba, 0x0d, 0x97, 0xbb, 0x3c, 0x16, 0x32, 0x3b, 0xec, 0xca, 0x17, 0x80, 0x2b, 0x29, 0x5e,
0xbe, 0x17, 0xbc, 0x07, 0x5a, 0xf3, 0x0c, 0xf5, 0x47, 0x2f, 0x2a, 0x40, 0x5f, 0x0a, 0x5c, 0x99,
0x52, 0xba, 0x0a, 0x57, 0xc3, 0x50, 0x7b, 0xfc, 0x70, 0x70, 0xb6, 0x9a, 0xd3, 0x57, 0x02, 0xf1,
0x47, 0x5c, 0xaa, 0x3e, 0xcc, 0xc1, 0x4a, 0x78, 0xbb, 0xb4, 0x07, 0x3d, 0x6a, 0x7b, 0x3d, 0xb4,
0xb3, 0x87, 0xed, 0x2e, 0x0a, 0xe1, 0xcd, 0x7a, 0x26, 0x80, 0xff, 0xc2, 0x33, 0x61, 0xf6, 0x95,
0x9e, 0x09, 0xb9, 0x49, 0xcf, 0x84, 0xb9, 0x09, 0xcf, 0x84, 0x7c, 0xfc, 0x99, 0x70, 0x0b, 0x2e,
0x31, 0x86, 0xea, 0x04, 0x14, 0x58, 0xe0, 0x5d, 0x52, 0x27, 0xbc, 0x01, 0xc6, 0x14, 0x48, 0xf4,
0xc5, 0xe1, 0x78, 0x91, 0x1c, 0xa6, 0x8f, 0xe1, 0xd5, 0x53, 0xfa, 0x70, 0xe6, 0x3b, 0x7f, 0xf3,
0xaf, 0x3c, 0xcc, 0xb5, 0x89, 0x25, 0x7d, 0x05, 0x57, 0x12, 0x6f, 0xc4, 0x6a, 0x22, 0xcb, 0xd4,
0xc3, 0x42, 0xa9, 0x9d, 0x66, 0x11, 0xa6, 0x81, 0xe0, 0x5a, 0xfa, 0x55, 0x71, 0x25, 0xed, 0x9e,
0x32, 0x52, 0xae, 0x9d, 0xc1, 0x28, 0xdc, 0xe6, 0x5d, 0x38, 0xc7, 0xaf, 0xf7, 0xf3, 0x69, 0x27,
0x26, 0x57, 0xca, 0xd9, 0xf2, 0xd0, 0xff, 0x3e, 0x5c, 0x8a, 0xdd, 0x91, 0x13, 0xec, 0x03, 0xbd,
0xf2, 0xda, 0x74, 0x7d, 0x18, 0xf7, 0x43, 0x58, 0x0c, 0x66, 0x72, 0x3d, 0xed, 0x22, 0x54, 0xca,
0xe5, 0x89, 0xaa, 0x68, 0x82, 0x31, 0xa2, 0xce, 0x48, 0x30, 0xaa, 0xcf, 0x4a, 0x30, 0x8b, 0x2b,
0x59, 0xf7, 0x13, 0x3c, 0x99, 0xd1, 0xfd, 0xb8, 0x45, 0x56, 0xf7, 0x27, 0xd0, 0xdb, 0x43, 0x00,
0x2f, 0x4d, 0x65, 0x0d, 0x6d, 0xd2, 0x20, 0x65, 0xdb, 0x2b, 0xdb, 0x2f, 0x67, 0x1f, 0x24, 0xa2,
0xe4, 0xbf, 0x61, 0x3c, 0xd1, 0xda, 0x7a, 0x7a, 0x54, 0x06, 0xcf, 0x8e, 0xca, 0xe0, 0xd7, 0xa3,
0x32, 0x78, 0x74, 0x5c, 0x9e, 0x79, 0x76, 0x5c, 0x9e, 0xf9, 0xe5, 0xb8, 0x3c, 0xf3, 0xe5, 0x45,
0x3f, 0x2e, 0x31, 0x1f, 0x68, 0x36, 0x16, 0xb7, 0x0e, 0xe7, 0x1d, 0xf6, 0x63, 0xb0, 0xc0, 0x49,
0xf5, 0xcd, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x9b, 0x54, 0x57, 0x4c, 0x0e, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -969,6 +1120,10 @@ type MsgClient interface {
//
// Since: cosmos-sdk 0.50
CancelProposal(ctx context.Context, in *MsgCancelProposal, opts ...grpc.CallOption) (*MsgCancelProposalResponse, error)
// SubmitMultipleChoiceProposal defines a method to create new multiple choice proposal.
//
// Since: x/gov 1.0.0
SubmitMultipleChoiceProposal(ctx context.Context, in *MsgSubmitMultipleChoiceProposal, opts ...grpc.CallOption) (*MsgSubmitMultipleChoiceProposalResponse, error)
}
type msgClient struct {
@ -1042,6 +1197,15 @@ func (c *msgClient) CancelProposal(ctx context.Context, in *MsgCancelProposal, o
return out, nil
}
func (c *msgClient) SubmitMultipleChoiceProposal(ctx context.Context, in *MsgSubmitMultipleChoiceProposal, opts ...grpc.CallOption) (*MsgSubmitMultipleChoiceProposalResponse, error) {
out := new(MsgSubmitMultipleChoiceProposalResponse)
err := c.cc.Invoke(ctx, "/cosmos.gov.v1.Msg/SubmitMultipleChoiceProposal", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MsgServer is the server API for Msg service.
type MsgServer interface {
// SubmitProposal defines a method to create new proposal given the messages.
@ -1064,6 +1228,10 @@ type MsgServer interface {
//
// Since: cosmos-sdk 0.50
CancelProposal(context.Context, *MsgCancelProposal) (*MsgCancelProposalResponse, error)
// SubmitMultipleChoiceProposal defines a method to create new multiple choice proposal.
//
// Since: x/gov 1.0.0
SubmitMultipleChoiceProposal(context.Context, *MsgSubmitMultipleChoiceProposal) (*MsgSubmitMultipleChoiceProposalResponse, error)
}
// UnimplementedMsgServer can be embedded to have forward compatible implementations.
@ -1091,6 +1259,9 @@ func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateP
func (*UnimplementedMsgServer) CancelProposal(ctx context.Context, req *MsgCancelProposal) (*MsgCancelProposalResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CancelProposal not implemented")
}
func (*UnimplementedMsgServer) SubmitMultipleChoiceProposal(ctx context.Context, req *MsgSubmitMultipleChoiceProposal) (*MsgSubmitMultipleChoiceProposalResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SubmitMultipleChoiceProposal not implemented")
}
func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
s.RegisterService(&_Msg_serviceDesc, srv)
@ -1222,6 +1393,24 @@ func _Msg_CancelProposal_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
func _Msg_SubmitMultipleChoiceProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgSubmitMultipleChoiceProposal)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).SubmitMultipleChoiceProposal(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.gov.v1.Msg/SubmitMultipleChoiceProposal",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).SubmitMultipleChoiceProposal(ctx, req.(*MsgSubmitMultipleChoiceProposal))
}
return interceptor(ctx, in, info, handler)
}
var _Msg_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.gov.v1.Msg",
HandlerType: (*MsgServer)(nil),
@ -1254,6 +1443,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{
MethodName: "CancelProposal",
Handler: _Msg_CancelProposal_Handler,
},
{
MethodName: "SubmitMultipleChoiceProposal",
Handler: _Msg_SubmitMultipleChoiceProposal_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/gov/v1/tx.proto",
@ -1806,6 +1999,111 @@ func (m *MsgCancelProposalResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro
return len(dAtA) - i, nil
}
func (m *MsgSubmitMultipleChoiceProposal) 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 *MsgSubmitMultipleChoiceProposal) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *MsgSubmitMultipleChoiceProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.VoteOptions != nil {
{
size, err := m.VoteOptions.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTx(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x32
}
if len(m.Summary) > 0 {
i -= len(m.Summary)
copy(dAtA[i:], m.Summary)
i = encodeVarintTx(dAtA, i, uint64(len(m.Summary)))
i--
dAtA[i] = 0x2a
}
if len(m.Title) > 0 {
i -= len(m.Title)
copy(dAtA[i:], m.Title)
i = encodeVarintTx(dAtA, i, uint64(len(m.Title)))
i--
dAtA[i] = 0x22
}
if len(m.Metadata) > 0 {
i -= len(m.Metadata)
copy(dAtA[i:], m.Metadata)
i = encodeVarintTx(dAtA, i, uint64(len(m.Metadata)))
i--
dAtA[i] = 0x1a
}
if len(m.Proposer) > 0 {
i -= len(m.Proposer)
copy(dAtA[i:], m.Proposer)
i = encodeVarintTx(dAtA, i, uint64(len(m.Proposer)))
i--
dAtA[i] = 0x12
}
if len(m.InitialDeposit) > 0 {
for iNdEx := len(m.InitialDeposit) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.InitialDeposit[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTx(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *MsgSubmitMultipleChoiceProposalResponse) 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 *MsgSubmitMultipleChoiceProposalResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *MsgSubmitMultipleChoiceProposalResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.ProposalId != 0 {
i = encodeVarintTx(dAtA, i, uint64(m.ProposalId))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintTx(dAtA []byte, offset int, v uint64) int {
offset -= sovTx(v)
base := offset
@ -2053,6 +2351,53 @@ func (m *MsgCancelProposalResponse) Size() (n int) {
return n
}
func (m *MsgSubmitMultipleChoiceProposal) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.InitialDeposit) > 0 {
for _, e := range m.InitialDeposit {
l = e.Size()
n += 1 + l + sovTx(uint64(l))
}
}
l = len(m.Proposer)
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
l = len(m.Metadata)
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
l = len(m.Title)
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
l = len(m.Summary)
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
if m.VoteOptions != nil {
l = m.VoteOptions.Size()
n += 1 + l + sovTx(uint64(l))
}
return n
}
func (m *MsgSubmitMultipleChoiceProposalResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ProposalId != 0 {
n += 1 + sovTx(uint64(m.ProposalId))
}
return n
}
func sovTx(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -3572,6 +3917,323 @@ func (m *MsgCancelProposalResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *MsgSubmitMultipleChoiceProposal) 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 ErrIntOverflowTx
}
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: MsgSubmitMultipleChoiceProposal: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MsgSubmitMultipleChoiceProposal: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field InitialDeposit", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.InitialDeposit = append(m.InitialDeposit, types1.Coin{})
if err := m.InitialDeposit[len(m.InitialDeposit)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Proposer", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Proposer = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Metadata = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Title = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Summary", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Summary = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteOptions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.VoteOptions == nil {
m.VoteOptions = &ProposalVoteOptions{}
}
if err := m.VoteOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTx(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTx
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MsgSubmitMultipleChoiceProposalResponse) 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 ErrIntOverflowTx
}
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: MsgSubmitMultipleChoiceProposalResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MsgSubmitMultipleChoiceProposalResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ProposalId", wireType)
}
m.ProposalId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ProposalId |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTx(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTx
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTx(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -18,10 +18,10 @@ const (
OptionFour = VoteOption_VOTE_OPTION_FOUR
OptionSpam = VoteOption_VOTE_OPTION_SPAM
OptionYes = OptionOne
OptionNo = OptionThree
OptionNoWithVeto = OptionFour
OptionAbstain = OptionTwo
OptionYes = VoteOption_VOTE_OPTION_YES
OptionNo = VoteOption_VOTE_OPTION_NO
OptionNoWithVeto = VoteOption_VOTE_OPTION_NO_WITH_VETO
OptionAbstain = VoteOption_VOTE_OPTION_ABSTAIN
)
// NewVote creates a new Vote instance