feat(x/protocolpool): Stream funds from community pool (#18103)

This commit is contained in:
Likhita Polavarapu 2023-11-06 19:37:34 +05:30 committed by GitHub
parent 9c0256e368
commit 56351179b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 8727 additions and 236 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
// Since: cosmos-sdk 0.50
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
@ -21,7 +19,8 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Query_CommunityPool_FullMethodName = "/cosmos.protocolpool.v1.Query/CommunityPool"
Query_CommunityPool_FullMethodName = "/cosmos.protocolpool.v1.Query/CommunityPool"
Query_UnclaimedBudget_FullMethodName = "/cosmos.protocolpool.v1.Query/UnclaimedBudget"
)
// QueryClient is the client API for Query service.
@ -30,6 +29,8 @@ const (
type QueryClient interface {
// CommunityPool queries the community pool coins.
CommunityPool(ctx context.Context, in *QueryCommunityPoolRequest, opts ...grpc.CallOption) (*QueryCommunityPoolResponse, error)
// UnclaimedBudget queries the remaining budget left to be claimed and it gives overall budget allocation view.
UnclaimedBudget(ctx context.Context, in *QueryUnclaimedBudgetRequest, opts ...grpc.CallOption) (*QueryUnclaimedBudgetResponse, error)
}
type queryClient struct {
@ -49,12 +50,23 @@ func (c *queryClient) CommunityPool(ctx context.Context, in *QueryCommunityPoolR
return out, nil
}
func (c *queryClient) UnclaimedBudget(ctx context.Context, in *QueryUnclaimedBudgetRequest, opts ...grpc.CallOption) (*QueryUnclaimedBudgetResponse, error) {
out := new(QueryUnclaimedBudgetResponse)
err := c.cc.Invoke(ctx, Query_UnclaimedBudget_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
type QueryServer interface {
// CommunityPool queries the community pool coins.
CommunityPool(context.Context, *QueryCommunityPoolRequest) (*QueryCommunityPoolResponse, error)
// UnclaimedBudget queries the remaining budget left to be claimed and it gives overall budget allocation view.
UnclaimedBudget(context.Context, *QueryUnclaimedBudgetRequest) (*QueryUnclaimedBudgetResponse, error)
mustEmbedUnimplementedQueryServer()
}
@ -65,6 +77,9 @@ type UnimplementedQueryServer struct {
func (UnimplementedQueryServer) CommunityPool(context.Context, *QueryCommunityPoolRequest) (*QueryCommunityPoolResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CommunityPool not implemented")
}
func (UnimplementedQueryServer) UnclaimedBudget(context.Context, *QueryUnclaimedBudgetRequest) (*QueryUnclaimedBudgetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnclaimedBudget not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
@ -96,6 +111,24 @@ func _Query_CommunityPool_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler)
}
func _Query_UnclaimedBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryUnclaimedBudgetRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).UnclaimedBudget(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_UnclaimedBudget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).UnclaimedBudget(ctx, req.(*QueryUnclaimedBudgetRequest))
}
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)
@ -107,6 +140,10 @@ var Query_ServiceDesc = grpc.ServiceDesc{
MethodName: "CommunityPool",
Handler: _Query_CommunityPool_Handler,
},
{
MethodName: "UnclaimedBudget",
Handler: _Query_UnclaimedBudget_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/protocolpool/v1/query.proto",

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
// Since: cosmos-sdk 0.50
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
@ -21,8 +19,10 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Msg_FundCommunityPool_FullMethodName = "/cosmos.protocolpool.v1.Msg/FundCommunityPool"
Msg_CommunityPoolSpend_FullMethodName = "/cosmos.protocolpool.v1.Msg/CommunityPoolSpend"
Msg_FundCommunityPool_FullMethodName = "/cosmos.protocolpool.v1.Msg/FundCommunityPool"
Msg_CommunityPoolSpend_FullMethodName = "/cosmos.protocolpool.v1.Msg/CommunityPoolSpend"
Msg_SubmitBudgetProposal_FullMethodName = "/cosmos.protocolpool.v1.Msg/SubmitBudgetProposal"
Msg_ClaimBudget_FullMethodName = "/cosmos.protocolpool.v1.Msg/ClaimBudget"
)
// MsgClient is the client API for Msg service.
@ -31,16 +31,16 @@ const (
type MsgClient interface {
// FundCommunityPool defines a method to allow an account to directly
// fund the community pool.
//
// Since: cosmos-sdk 0.50
FundCommunityPool(ctx context.Context, in *MsgFundCommunityPool, opts ...grpc.CallOption) (*MsgFundCommunityPoolResponse, error)
// CommunityPoolSpend defines a governance operation for sending tokens from
// the community pool in the x/protocolpool module to another account, which
// could be the governance module itself. The authority is defined in the
// keeper.
//
// Since: cosmos-sdk 0.50
CommunityPoolSpend(ctx context.Context, in *MsgCommunityPoolSpend, opts ...grpc.CallOption) (*MsgCommunityPoolSpendResponse, error)
// SubmitBudgetProposal defines a method to set a budget proposal.
SubmitBudgetProposal(ctx context.Context, in *MsgSubmitBudgetProposal, opts ...grpc.CallOption) (*MsgSubmitBudgetProposalResponse, error)
// ClaimBudget defines a method to claim the distributed budget.
ClaimBudget(ctx context.Context, in *MsgClaimBudget, opts ...grpc.CallOption) (*MsgClaimBudgetResponse, error)
}
type msgClient struct {
@ -69,22 +69,40 @@ func (c *msgClient) CommunityPoolSpend(ctx context.Context, in *MsgCommunityPool
return out, nil
}
func (c *msgClient) SubmitBudgetProposal(ctx context.Context, in *MsgSubmitBudgetProposal, opts ...grpc.CallOption) (*MsgSubmitBudgetProposalResponse, error) {
out := new(MsgSubmitBudgetProposalResponse)
err := c.cc.Invoke(ctx, Msg_SubmitBudgetProposal_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *msgClient) ClaimBudget(ctx context.Context, in *MsgClaimBudget, opts ...grpc.CallOption) (*MsgClaimBudgetResponse, error) {
out := new(MsgClaimBudgetResponse)
err := c.cc.Invoke(ctx, Msg_ClaimBudget_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
type MsgServer interface {
// FundCommunityPool defines a method to allow an account to directly
// fund the community pool.
//
// Since: cosmos-sdk 0.50
FundCommunityPool(context.Context, *MsgFundCommunityPool) (*MsgFundCommunityPoolResponse, error)
// CommunityPoolSpend defines a governance operation for sending tokens from
// the community pool in the x/protocolpool module to another account, which
// could be the governance module itself. The authority is defined in the
// keeper.
//
// Since: cosmos-sdk 0.50
CommunityPoolSpend(context.Context, *MsgCommunityPoolSpend) (*MsgCommunityPoolSpendResponse, error)
// SubmitBudgetProposal defines a method to set a budget proposal.
SubmitBudgetProposal(context.Context, *MsgSubmitBudgetProposal) (*MsgSubmitBudgetProposalResponse, error)
// ClaimBudget defines a method to claim the distributed budget.
ClaimBudget(context.Context, *MsgClaimBudget) (*MsgClaimBudgetResponse, error)
mustEmbedUnimplementedMsgServer()
}
@ -98,6 +116,12 @@ func (UnimplementedMsgServer) FundCommunityPool(context.Context, *MsgFundCommuni
func (UnimplementedMsgServer) CommunityPoolSpend(context.Context, *MsgCommunityPoolSpend) (*MsgCommunityPoolSpendResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CommunityPoolSpend not implemented")
}
func (UnimplementedMsgServer) SubmitBudgetProposal(context.Context, *MsgSubmitBudgetProposal) (*MsgSubmitBudgetProposalResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SubmitBudgetProposal not implemented")
}
func (UnimplementedMsgServer) ClaimBudget(context.Context, *MsgClaimBudget) (*MsgClaimBudgetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ClaimBudget not implemented")
}
func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {}
// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service.
@ -147,6 +171,42 @@ func _Msg_CommunityPoolSpend_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _Msg_SubmitBudgetProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgSubmitBudgetProposal)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).SubmitBudgetProposal(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_SubmitBudgetProposal_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).SubmitBudgetProposal(ctx, req.(*MsgSubmitBudgetProposal))
}
return interceptor(ctx, in, info, handler)
}
func _Msg_ClaimBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgClaimBudget)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).ClaimBudget(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_ClaimBudget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).ClaimBudget(ctx, req.(*MsgClaimBudget))
}
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)
@ -162,6 +222,14 @@ var Msg_ServiceDesc = grpc.ServiceDesc{
MethodName: "CommunityPoolSpend",
Handler: _Msg_CommunityPoolSpend_Handler,
},
{
MethodName: "SubmitBudgetProposal",
Handler: _Msg_SubmitBudgetProposal_Handler,
},
{
MethodName: "ClaimBudget",
Handler: _Msg_ClaimBudget_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/protocolpool/v1/tx.proto",

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,3 @@
// Since: cosmos-sdk 0.50
syntax = "proto3";
package cosmos.protocolpool.v1;
@ -7,6 +6,9 @@ option go_package = "cosmossdk.io/x/protocolpool/types";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
// Query defines the gRPC querier service for community pool module.
service Query {
@ -14,6 +16,11 @@ service Query {
rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) {
option (google.api.http).get = "/cosmos/protocolpool/v1/community_pool";
}
// UnclaimedBudget queries the remaining budget left to be claimed and it gives overall budget allocation view.
rpc UnclaimedBudget(QueryUnclaimedBudgetRequest) returns (QueryUnclaimedBudgetResponse) {
option (google.api.http).get = "/cosmos/protocolpool/v1/unclaimed_budget/{address}";
}
}
// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC
@ -27,3 +34,28 @@ message QueryCommunityPoolResponse {
repeated cosmos.base.v1beta1.DecCoin pool = 1
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false];
}
// QueryUnclaimedBudgetRequest is the request type for the Query/UnclaimedBudgetRequest
// RPC method.
message QueryUnclaimedBudgetRequest {
// address is the recipient address to query unclaimed budget amount for.
string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// QueryUnclaimedBudgetResponse is the response type for the Query/UnclaimedBudget
// RPC method.
message QueryUnclaimedBudgetResponse {
// total_budget is the total budget allocated to the recipient
cosmos.base.v1beta1.Coin total_budget = 1;
// claimed_amount is the budget amount already claimed by the recipient
cosmos.base.v1beta1.Coin claimed_amount = 2;
// unclaimed_amount is the remaining budget amount that is unclaimed by the recipient
cosmos.base.v1beta1.Coin unclaimed_amount = 3;
// next_claim_from is the next starting claim time for fund distribution.
// It represents the time when we can claim funds after the period time interval has passed.
google.protobuf.Timestamp next_claim_from = 4 [(gogoproto.stdtime) = true];
// period is the time interval for fund distribution
google.protobuf.Duration period = 5 [(gogoproto.stdduration) = true];
// tranches_left is the number of tranches left for the amount to be distributed
uint64 tranches_left = 6;
}

View File

@ -1,4 +1,3 @@
// Since: cosmos-sdk 0.50
syntax = "proto3";
package cosmos.protocolpool.v1;
@ -8,6 +7,8 @@ import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/msg/v1/msg.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
// Msg defines the pool Msg service.
service Msg {
@ -15,17 +16,19 @@ service Msg {
// FundCommunityPool defines a method to allow an account to directly
// fund the community pool.
//
// Since: cosmos-sdk 0.50
rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
// CommunityPoolSpend defines a governance operation for sending tokens from
// the community pool in the x/protocolpool module to another account, which
// could be the governance module itself. The authority is defined in the
// keeper.
//
// Since: cosmos-sdk 0.50
rpc CommunityPoolSpend(MsgCommunityPoolSpend) returns (MsgCommunityPoolSpendResponse);
// SubmitBudgetProposal defines a method to set a budget proposal.
rpc SubmitBudgetProposal(MsgSubmitBudgetProposal) returns (MsgSubmitBudgetProposalResponse);
// ClaimBudget defines a method to claim the distributed budget.
rpc ClaimBudget(MsgClaimBudget) returns (MsgClaimBudgetResponse);
}
// MsgFundCommunityPool allows an account to directly
@ -46,8 +49,6 @@ message MsgFundCommunityPoolResponse {}
// MsgCommunityPoolSpend defines a message for sending tokens from the community
// pool to another account. This message is typically executed via a governance
// proposal with the governance module being the executing authority.
//
// Since: cosmos-sdk 0.50
message MsgCommunityPoolSpend {
option (cosmos.msg.v1.signer) = "authority";
@ -60,6 +61,43 @@ message MsgCommunityPoolSpend {
// MsgCommunityPoolSpendResponse defines the response to executing a
// MsgCommunityPoolSpend message.
//
// Since: cosmos-sdk 0.50
message MsgCommunityPoolSpendResponse {}
message MsgCommunityPoolSpendResponse {}
// MsgSubmitBudgetProposal defines budget proposal type.
message MsgSubmitBudgetProposal {
option (cosmos.msg.v1.signer) = "authority";
// authority is the address that controls the module (defaults to x/gov unless overwritten).
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// recipient_address is the address of the recipient who can claim the budget.
string recipient_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// total_budget is the total amount allocated for the budget.
cosmos.base.v1beta1.Coin total_budget = 3;
// start_time is the time when the budget becomes claimable.
// If start_time is less than the current block time, proposal will not be accepted.
google.protobuf.Timestamp start_time = 4 [(gogoproto.stdtime) = true];
// tranches is the number of times the total budget amount is to be distributed.
uint64 tranches = 5;
// Period is the time interval(number of seconds) at which funds distribution should be performed.
// For example, if a period is set to 3600, it represents an action that
// should occur every hour (3600 seconds).
google.protobuf.Duration period = 6 [(gogoproto.stdduration) = true];
}
// MsgSubmitBudgetProposalResponse defines the response to executing a
// MsgSubmitBudgetProposal message.
message MsgSubmitBudgetProposalResponse {}
// MsgClaimBudget defines a message for claiming the distributed budget.
message MsgClaimBudget {
option (cosmos.msg.v1.signer) = "recipient_address";
string recipient_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// MsgClaimBudgetResponse defines the response to executing a
// MsgClaimBudget message.
message MsgClaimBudgetResponse {
cosmos.base.v1beta1.Coin amount = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
;
}

View File

@ -0,0 +1,33 @@
syntax = "proto3";
package cosmos.protocolpool.v1;
option go_package = "cosmossdk.io/x/protocolpool/types";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
// Budget defines the fields of a budget proposal.
message Budget {
// recipient_address is the address of the recipient who can claim the budget.
string recipient_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// total_budget is the total amount allocated for the budget.
cosmos.base.v1beta1.Coin total_budget = 2;
// claimed_amount is the total amount claimed from the total budget amount requested.
cosmos.base.v1beta1.Coin claimed_amount = 3;
// start_time is the time when the budget becomes claimable.
google.protobuf.Timestamp start_time = 4 [(gogoproto.stdtime) = true];
// next_claim_from is the time when the budget was last successfully claimed or distributed.
// It is used to track the next starting claim time for fund distribution. If set, it cannot be less than start_time.
google.protobuf.Timestamp next_claim_from = 5 [(gogoproto.stdtime) = true];
// tranches is the number of times the total budget amount is to be distributed.
uint64 tranches = 6;
// tranches_left is the number of tranches left for the amount to be distributed.
uint64 tranches_left = 7;
// Period is the time interval(number of seconds) at which funds distribution should be performed.
// For example, if a period is set to 3600, it represents an action that
// should occur every hour (3600 seconds).
google.protobuf.Duration period = 8 [(gogoproto.stdduration) = true];
}

View File

@ -476,6 +476,7 @@ func NewSimApp(
genutiltypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
pooltypes.ModuleName,
)
// NOTE: The genutils module must occur after staking so that pools are

View File

@ -128,6 +128,7 @@ var (
stakingtypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
pooltypes.ModuleName,
},
OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
{

View File

@ -81,6 +81,7 @@ func defaultConfig() *Config {
"upgrade",
"vesting",
"circuit",
"protocolpool",
},
InitGenesisOrder: []string{
"auth",

View File

@ -45,6 +45,10 @@ var suggestedProposalTypes = []proposalType{
Name: "cancel-software-upgrade",
MsgType: "/cosmos.upgrade.v1beta1.MsgCancelUpgrade",
},
{
Name: "submit-budget-proposal",
MsgType: "/cosmos.protocolpool.v1.MsgSubmitBudgetProposal",
},
{
Name: proposalOther,
MsgType: "", // user will input the message type

View File

@ -8,6 +8,8 @@ sidebar_position: 1
Protopool is a module that handle functionality around community pool funds. This provides a separate module account for community pool making it easier to track the pool assets. We no longer track community pool assets in distribution module, but instead in this protocolpool module. Funds are migrated from the distribution module's community pool to protocolpool's module account.
The module is also designed with a lazy "claim-based" system, which means that users are required to actively claim allocated funds from allocated budget if any budget proposal has been submitted and passed. The module does not automatically distribute funds to recipients. This design choice allows for more flexibility and control over fund distribution.
## State Transitions
### FundCommunityPool
@ -32,6 +34,27 @@ CommunityPoolSpend can be called by the module authority (default governance mod
rpc CommunityPoolSpend(MsgCommunityPoolSpend) returns (MsgCommunityPoolSpendResponse);
```
### SubmitBudgetProposal
SubmitBudgetProposal is a message used to propose a budget allocation for a specific recipient. The proposed funds will be distributed periodically over a specified time frame.
It's the responsibility of users to actively claim their allocated funds based on the terms of the approved budget proposals.
```protobuf
// SubmitBudgetProposal defines a method to set a budget proposal.
rpc SubmitBudgetProposal(MsgSubmitBudgetProposal) returns (MsgSubmitBudgetProposalResponse);
```
### ClaimBudget
ClaimBudget is a message used to claim funds from a previously submitted budget proposal. When a budget proposal is approved and funds are allocated, recipients can use this message to claim their share of the budget. Funds are distributed in tranches over specific periods, and users can claim their share of budget at the appropriate time.
```protobuf
// ClaimBudget defines a method to claim the distributed budget.
rpc ClaimBudget(MsgClaimBudget) returns (MsgClaimBudgetResponse);
```
## Messages
### MsgFundCommunityPool
@ -43,7 +66,7 @@ If you know the protocolpool module account address, you can directly use bank `
::::
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/9dd34510e27376005e7e7ff3628eab9dbc8ad6dc/proto/cosmos/protocolpool/v1/tx.proto#L31-L41
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/proto/cosmos/protocolpool/v1/tx.proto#L32-L42
```
* The msg will fail if the amount cannot be transferred from the sender to the protocolpool module account.
@ -59,7 +82,7 @@ func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender
This message distributes funds from the protocolpool module account to the recipient using `DistributeFromFeePool` keeper method.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/9dd34510e27376005e7e7ff3628eab9dbc8ad6dc/proto/cosmos/protocolpool/v1/tx.proto#L46-L59
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/proto/cosmos/protocolpool/v1/tx.proto#L47-L58
```
The message will fail under the following conditions:
@ -73,6 +96,50 @@ func (k Keeper) DistributeFromFeePool(ctx context.Context, amount sdk.Coins, rec
}
```
### MsgSubmitBudgetProposal
This message is used to submit a budget proposal to allocate funds for a specific recipient. The proposed funds will be distributed periodically over a specified time frame.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/proto/cosmos/protocolpool/v1/tx.proto#L64-L82
```
The message will fail under the following conditions:
* The total budget is zero.
* The recipient address is empty or restricted.
* The start time is less than current block time.
* The number of tranches is not a positive integer.
* The period length is not a positive integer.
:::warning
If two budgets to the same address are created, the budget would be updated with the new budget.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/x/protocolpool/keeper/msg_server.go#L39-l61
```
### MsgClaimBudget
This message is used to claim funds from a previously submitted budget proposal. When a budget proposal is passed and funds are allocated, recipients can use this message to claim their share of the budget.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/proto/cosmos/protocolpool/v1/tx.proto#L88-L92
```
The message will fail under the following conditions:
- The recipient address is empty or restricted.
- The budget proposal for the recipient does not exist.
- The budget proposal has not reached its distribution start time.
- The budget proposal's distribution period has not passed yet.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/97724493d792517ba2be8969078b5f92ad04d79c/x/protocolpool/keeper/msg_server.go#L25-L37
```
## Client
It takes the advantage of `AutoCLI`

View File

@ -19,7 +19,14 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
RpcMethod: "CommunityPool",
Use: "community-pool",
Short: "Query the amount of coins in the community pool",
Example: fmt.Sprintf(`$ %s query pool community-pool`, version.AppName),
Example: fmt.Sprintf(`$ %s query protocolpool community-pool`, version.AppName),
},
{
RpcMethod: "UnclaimedBudget",
Use: "unclaimed-budget [recipient-address]",
Short: "Query the remaining budget left to be claimed",
Example: fmt.Sprintf(`$ %s query protocolpool unclaimed-budget cosmos1...`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "address"}},
},
},
},
@ -33,6 +40,26 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Example: fmt.Sprintf(`$ %s tx protocolpool fund-community-pool 100uatom --from mykey`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "amount"}},
},
{
RpcMethod: "SubmitBudgetProposal",
Use: "submit-budget-proposal [recipient] [total-budget] [start-time] [tranches] [period]",
Short: "Submit a budget proposal",
Example: fmt.Sprintf(`$ %s tx protocolpool submit-budget-proposal cosmos1... 1000000uatom 1600000000 10 1000 --from mykey`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "recipient_address"},
{ProtoField: "total_budget"},
{ProtoField: "start_time"},
{ProtoField: "tranches"},
{ProtoField: "period"},
},
},
{
RpcMethod: "ClaimBudget",
Use: "claim-budget [recipient]",
Short: "Claim the distributed budget",
Example: fmt.Sprintf(`$ %s tx protocolpool claim-budget cosmos1... --from mykey`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "recipient_address"}},
},
},
},
}

View File

@ -4,10 +4,13 @@ go 1.21
require (
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.12.0
cosmossdk.io/depinject v1.0.0-alpha.4
cosmossdk.io/errors v1.0.0
cosmossdk.io/log v1.2.1
cosmossdk.io/math v1.1.3-rc.1
cosmossdk.io/store v1.0.0
cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000
cosmossdk.io/x/distribution v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/gov v0.0.0-20230925135524-a1bc045b3190
@ -22,13 +25,11 @@ require (
github.com/stretchr/testify v1.8.4
google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
gotest.tools/v3 v3.5.1
)
require (
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/math v1.1.3-rc.1 // indirect
cosmossdk.io/store v1.0.0 // indirect
cosmossdk.io/x/tx v0.12.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
@ -153,7 +154,6 @@ require (
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@ -2,7 +2,13 @@ package keeper
import (
"context"
"errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"cosmossdk.io/collections"
"cosmossdk.io/math"
"cosmossdk.io/x/protocolpool/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -27,3 +33,46 @@ func (k Querier) CommunityPool(ctx context.Context, req *types.QueryCommunityPoo
decCoins := sdk.NewDecCoinsFromCoins(amount...)
return &types.QueryCommunityPoolResponse{Pool: decCoins}, nil
}
// UnclaimedBudget queries the unclaimed budget for given recipient
func (k Querier) UnclaimedBudget(ctx context.Context, req *types.QueryUnclaimedBudgetRequest) (*types.QueryUnclaimedBudgetResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
address, err := k.Keeper.authKeeper.AddressCodec().StringToBytes(req.Address)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid recipient address: %s", err.Error())
}
budget, err := k.Keeper.BudgetProposal.Get(ctx, address)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return nil, status.Errorf(codes.NotFound, "no budget proposal found for address: %s", req.Address)
}
return nil, err
}
var unclaimedBudget sdk.Coin
if budget.ClaimedAmount == nil {
unclaimedBudget = *budget.TotalBudget
zeroCoin := sdk.NewCoin(budget.TotalBudget.Denom, math.ZeroInt())
budget.ClaimedAmount = &zeroCoin
} else {
unclaimedBudget = budget.TotalBudget.Sub(*budget.ClaimedAmount)
}
if budget.NextClaimFrom == nil {
budget.NextClaimFrom = budget.StartTime
}
if budget.TranchesLeft == 0 {
budget.TranchesLeft = budget.Tranches
}
return &types.QueryUnclaimedBudgetResponse{
TotalBudget: budget.TotalBudget,
ClaimedAmount: budget.ClaimedAmount,
UnclaimedAmount: &unclaimedBudget,
NextClaimFrom: budget.NextClaimFrom,
Period: budget.Period,
TranchesLeft: budget.TranchesLeft,
}, nil
}

View File

@ -0,0 +1,125 @@
package keeper_test
import (
"time"
"cosmossdk.io/math"
"cosmossdk.io/x/protocolpool/keeper"
"cosmossdk.io/x/protocolpool/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func (suite *KeeperTestSuite) TestUnclaimedBudget() {
queryServer := keeper.NewQuerier(suite.poolKeeper)
startTime := suite.ctx.BlockTime().Add(-70 * time.Second)
period := time.Duration(60) * time.Second
zeroCoin := sdk.NewCoin("foo", math.ZeroInt())
nextClaimFrom := startTime.Add(period)
testCases := []struct {
name string
preRun func()
req *types.QueryUnclaimedBudgetRequest
expErr bool
expErrMsg string
unclaimedFunds *sdk.Coin
resp *types.QueryUnclaimedBudgetResponse
}{
{
name: "empty recipient address",
req: &types.QueryUnclaimedBudgetRequest{
Address: "",
},
expErr: true,
expErrMsg: "empty address string is not allowed",
},
{
name: "no budget proposal found",
req: &types.QueryUnclaimedBudgetRequest{
Address: recipientAddr.String(),
},
expErr: true,
expErrMsg: "no budget proposal found for address",
},
{
name: "valid case",
preRun: func() {
// Prepare a valid budget proposal
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
},
req: &types.QueryUnclaimedBudgetRequest{
Address: recipientAddr.String(),
},
expErr: false,
unclaimedFunds: &fooCoin,
resp: &types.QueryUnclaimedBudgetResponse{
TotalBudget: &fooCoin,
ClaimedAmount: &zeroCoin,
UnclaimedAmount: &fooCoin,
NextClaimFrom: &startTime,
Period: &period,
TranchesLeft: 2,
},
},
{
name: "valid case with claim",
preRun: func() {
// Prepare a valid budget proposal
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
// Claim the funds once
msg := &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
suite.mockSendCoinsFromModuleToAccount(recipientAddr)
_, err = suite.msgServer.ClaimBudget(suite.ctx, msg)
suite.Require().NoError(err)
},
req: &types.QueryUnclaimedBudgetRequest{
Address: recipientAddr.String(),
},
expErr: false,
unclaimedFunds: &fooCoin2,
resp: &types.QueryUnclaimedBudgetResponse{
TotalBudget: &fooCoin,
ClaimedAmount: &fooCoin2,
UnclaimedAmount: &fooCoin2,
NextClaimFrom: &nextClaimFrom,
Period: &period,
TranchesLeft: 1,
},
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
if tc.preRun != nil {
tc.preRun()
}
resp, err := queryServer.UnclaimedBudget(suite.ctx, tc.req)
if tc.expErr {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.expErrMsg)
} else {
suite.Require().NoError(err)
suite.Require().Equal(tc.resp, resp)
}
})
}
}

View File

@ -2,11 +2,15 @@ package keeper
import (
"context"
"errors"
"fmt"
"time"
"cosmossdk.io/collections"
storetypes "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
"cosmossdk.io/math"
"cosmossdk.io/x/protocolpool/types"
"github.com/cosmos/cosmos-sdk/codec"
@ -19,7 +23,13 @@ type Keeper struct {
authKeeper types.AccountKeeper
bankKeeper types.BankKeeper
cdc codec.BinaryCodec
authority string
// State
Schema collections.Schema
BudgetProposal collections.Map[sdk.AccAddress, types.Budget]
}
func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService,
@ -29,12 +39,24 @@ func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService,
if addr := ak.GetModuleAddress(types.ModuleName); addr == nil {
panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
}
return Keeper{
storeService: storeService,
authKeeper: ak,
bankKeeper: bk,
authority: authority,
sb := collections.NewSchemaBuilder(storeService)
keeper := Keeper{
storeService: storeService,
authKeeper: ak,
bankKeeper: bk,
cdc: cdc,
authority: authority,
BudgetProposal: collections.NewMap(sb, types.BudgetKey, "budget", sdk.AccAddressKey, codec.CollValue[types.Budget](cdc)),
}
schema, err := sb.Build()
if err != nil {
panic(err)
}
keeper.Schema = schema
return keeper
}
// GetAuthority returns the x/protocolpool module's authority.
@ -67,3 +89,140 @@ func (k Keeper) GetCommunityPool(ctx context.Context) (sdk.Coins, error) {
}
return k.bankKeeper.GetAllBalances(ctx, moduleAccount.GetAddress()), nil
}
func (k Keeper) claimFunds(ctx context.Context, recipient sdk.AccAddress) (amount sdk.Coin, err error) {
// get claimable funds from distribution info
amount, err = k.getClaimableFunds(ctx, recipient)
if err != nil {
return sdk.Coin{}, fmt.Errorf("error getting claimable funds: %w", err)
}
// distribute amount from feepool
err = k.DistributeFromFeePool(ctx, sdk.NewCoins(amount), recipient)
if err != nil {
return sdk.Coin{}, fmt.Errorf("error distributing from fee pool: %w", err)
}
return amount, nil
}
func (k Keeper) getClaimableFunds(ctx context.Context, recipient sdk.AccAddress) (amount sdk.Coin, err error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
budget, err := k.BudgetProposal.Get(ctx, recipient)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return sdk.Coin{}, fmt.Errorf("no budget found for recipient: %s", recipient.String())
}
return sdk.Coin{}, err
}
// check if the distribution is completed
if budget.TranchesLeft == 0 && budget.ClaimedAmount != nil {
// check that claimed amount is equal to total budget
if budget.ClaimedAmount.Equal(budget.TotalBudget) {
// remove the entry of budget ended recipient
if err := k.BudgetProposal.Remove(ctx, recipient); err != nil {
return sdk.Coin{}, err
}
// Return the end of the budget
return sdk.Coin{}, fmt.Errorf("budget ended for recipient: %s", recipient.String())
}
}
currentTime := sdkCtx.BlockTime()
startTime := budget.StartTime
// Check if the start time is reached
if currentTime.Before(*startTime) {
return sdk.Coin{}, fmt.Errorf("distribution has not started yet")
}
if budget.NextClaimFrom == nil || budget.NextClaimFrom.IsZero() {
budget.NextClaimFrom = budget.StartTime
}
if budget.TranchesLeft == 0 && budget.ClaimedAmount == nil {
budget.TranchesLeft = budget.Tranches
zeroCoin := sdk.NewCoin(budget.TotalBudget.Denom, math.ZeroInt())
budget.ClaimedAmount = &zeroCoin
}
return k.calculateClaimableFunds(ctx, recipient, budget, currentTime)
}
func (k Keeper) calculateClaimableFunds(ctx context.Context, recipient sdk.AccAddress, budget types.Budget, currentTime time.Time) (amount sdk.Coin, err error) {
// Calculate the time elapsed since the last claim time
timeElapsed := currentTime.Sub(*budget.NextClaimFrom)
// Check the time elapsed has passed period length
if timeElapsed < *budget.Period {
return sdk.Coin{}, fmt.Errorf("budget period has not passed yet")
}
// Calculate how many periods have passed
periodsPassed := int64(timeElapsed) / int64(*budget.Period)
// Calculate the amount to distribute for all passed periods
coinsToDistribute := math.NewInt(periodsPassed).Mul(budget.TotalBudget.Amount.QuoRaw(int64(budget.Tranches)))
amount = sdk.NewCoin(budget.TotalBudget.Denom, coinsToDistribute)
// update the budget's remaining tranches
budget.TranchesLeft -= uint64(periodsPassed)
// update the ClaimedAmount
claimedAmount := budget.ClaimedAmount.Add(amount)
budget.ClaimedAmount = &claimedAmount
// Update the last claim time for the budget
nextClaimFrom := budget.NextClaimFrom.Add(*budget.Period)
budget.NextClaimFrom = &nextClaimFrom
k.Logger(ctx).Debug(fmt.Sprintf("Processing budget for recipient: %s. Amount: %s", budget.RecipientAddress, coinsToDistribute.String()))
// Save the updated budget in the state
if err := k.BudgetProposal.Set(ctx, recipient, budget); err != nil {
return sdk.Coin{}, fmt.Errorf("error while updating the budget for recipient %s", budget.RecipientAddress)
}
return amount, nil
}
func (k Keeper) validateAndUpdateBudgetProposal(ctx context.Context, bp types.MsgSubmitBudgetProposal) (*types.Budget, error) {
if bp.TotalBudget.IsZero() {
return nil, fmt.Errorf("invalid budget proposal: total budget cannot be zero")
}
if err := validateAmount(sdk.NewCoins(*bp.TotalBudget)); err != nil {
return nil, fmt.Errorf("invalid budget proposal: %w", err)
}
currentTime := sdk.UnwrapSDKContext(ctx).BlockTime()
if bp.StartTime.IsZero() || bp.StartTime == nil {
bp.StartTime = &currentTime
}
// if bp.StartTime < uint64(currentTime) {
if currentTime.After(*bp.StartTime) {
return nil, fmt.Errorf("invalid budget proposal: start time cannot be less than the current block time")
}
if bp.Tranches == 0 {
return nil, fmt.Errorf("invalid budget proposal: tranches must be greater than zero")
}
if bp.Period == nil || *bp.Period == 0 {
return nil, fmt.Errorf("invalid budget proposal: period length should be greater than zero")
}
// Create and return an updated budget proposal
updatedBudget := types.Budget{
RecipientAddress: bp.RecipientAddress,
TotalBudget: bp.TotalBudget,
StartTime: bp.StartTime,
Tranches: bp.Tranches,
Period: bp.Period,
}
return &updatedBudget, nil
}

View File

@ -0,0 +1,71 @@
package keeper_test
import (
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/header"
storetypes "cosmossdk.io/store/types"
poolkeeper "cosmossdk.io/x/protocolpool/keeper"
pooltestutil "cosmossdk.io/x/protocolpool/testutil"
pooltypes "cosmossdk.io/x/protocolpool/types"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var poolAcc = authtypes.NewEmptyModuleAccount(pooltypes.ModuleName)
type KeeperTestSuite struct {
suite.Suite
ctx sdk.Context
poolKeeper poolkeeper.Keeper
bankKeeper *pooltestutil.MockBankKeeper
msgServer pooltypes.MsgServer
}
func (s *KeeperTestSuite) SetupTest() {
key := storetypes.NewKVStoreKey(pooltypes.StoreKey)
storeService := runtime.NewKVStoreService(key)
testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithHeaderInfo(header.Info{Time: time.Now()})
encCfg := moduletestutil.MakeTestEncodingConfig()
// gomock initializations
ctrl := gomock.NewController(s.T())
accountKeeper := pooltestutil.NewMockAccountKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress(pooltypes.ModuleName).Return(poolAcc.GetAddress())
accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
bankKeeper := pooltestutil.NewMockBankKeeper(ctrl)
s.bankKeeper = bankKeeper
poolKeeper := poolkeeper.NewKeeper(
encCfg.Codec,
storeService,
accountKeeper,
bankKeeper,
authtypes.NewModuleAddress(pooltypes.GovModuleName).String(),
)
s.ctx = ctx
s.poolKeeper = poolKeeper
pooltypes.RegisterInterfaces(encCfg.InterfaceRegistry)
s.msgServer = poolkeeper.NewMsgServerImpl(poolKeeper)
}
func (s *KeeperTestSuite) mockSendCoinsFromModuleToAccount(accAddr sdk.AccAddress) {
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(s.ctx, pooltypes.ModuleName, accAddr, gomock.Any()).AnyTimes()
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

View File

@ -22,6 +22,44 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &MsgServer{Keeper: keeper}
}
func (k MsgServer) ClaimBudget(ctx context.Context, msg *types.MsgClaimBudget) (*types.MsgClaimBudgetResponse, error) {
recipient, err := k.Keeper.authKeeper.AddressCodec().StringToBytes(msg.RecipientAddress)
if err != nil {
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid recipient address: %s", err)
}
amount, err := k.claimFunds(ctx, recipient)
if err != nil {
return nil, err
}
return &types.MsgClaimBudgetResponse{Amount: amount}, nil
}
func (k MsgServer) SubmitBudgetProposal(ctx context.Context, msg *types.MsgSubmitBudgetProposal) (*types.MsgSubmitBudgetProposalResponse, error) {
if err := k.validateAuthority(msg.GetAuthority()); err != nil {
return nil, err
}
recipient, err := k.Keeper.authKeeper.AddressCodec().StringToBytes(msg.RecipientAddress)
if err != nil {
return nil, err
}
budgetProposal, err := k.validateAndUpdateBudgetProposal(ctx, *msg)
if err != nil {
return nil, err
}
// set budget proposal in state
// Note: If two budgets to the same address are created, the budget would be updated with the new budget.
err = k.BudgetProposal.Set(ctx, recipient, *budgetProposal)
if err != nil {
return nil, err
}
return &types.MsgSubmitBudgetProposalResponse{}, nil
}
func (k MsgServer) FundCommunityPool(ctx context.Context, msg *types.MsgFundCommunityPool) (*types.MsgFundCommunityPoolResponse, error) {
depositor, err := k.authKeeper.AddressCodec().StringToBytes(msg.Depositor)
if err != nil {

View File

@ -0,0 +1,339 @@
package keeper_test
import (
"time"
"cosmossdk.io/core/header"
"cosmossdk.io/x/protocolpool/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
recipientAddr = sdk.AccAddress([]byte("to1__________________"))
fooCoin = sdk.NewInt64Coin("foo", 100)
fooCoin2 = sdk.NewInt64Coin("foo", 50)
)
func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
invalidCoin := sdk.NewInt64Coin("foo", 0)
startTime := suite.ctx.BlockTime().Add(10 * time.Second)
invalidStartTime := suite.ctx.BlockTime().Add(-15 * time.Second)
period := time.Duration(60) * time.Second
zeroPeriod := time.Duration(0) * time.Second
testCases := map[string]struct {
preRun func()
input *types.MsgSubmitBudgetProposal
expErr bool
expErrMsg string
}{
"empty recipient address": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: "",
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
},
expErr: true,
expErrMsg: "empty address string is not allowed",
},
"empty authority": {
input: &types.MsgSubmitBudgetProposal{
Authority: "",
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
},
expErr: true,
expErrMsg: "empty address string is not allowed",
},
"invalid authority": {
input: &types.MsgSubmitBudgetProposal{
Authority: "invalid_authority",
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
},
expErr: true,
expErrMsg: "invalid authority",
},
"invalid budget": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &invalidCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
},
expErr: true,
expErrMsg: "total budget cannot be zero",
},
"invalid start time": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &invalidStartTime,
Tranches: 2,
Period: &period,
},
expErr: true,
expErrMsg: "start time cannot be less than the current block time",
},
"invalid tranches": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 0,
Period: &period,
},
expErr: true,
expErrMsg: "tranches must be greater than zero",
},
"invalid period": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &zeroPeriod,
},
expErr: true,
expErrMsg: "period length should be greater than zero",
},
"all good": {
input: &types.MsgSubmitBudgetProposal{
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
},
expErr: false,
},
}
for name, tc := range testCases {
suite.Run(name, func() {
suite.SetupTest()
if tc.preRun != nil {
tc.preRun()
}
_, err := suite.msgServer.SubmitBudgetProposal(suite.ctx, tc.input)
if tc.expErr {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.expErrMsg)
} else {
suite.Require().NoError(err)
}
})
}
}
func (suite *KeeperTestSuite) TestMsgClaimBudget() {
startTime := suite.ctx.BlockTime().Add(-70 * time.Second)
period := time.Duration(60) * time.Second
testCases := map[string]struct {
preRun func()
recipientAddress sdk.AccAddress
expErr bool
expErrMsg string
claimableFunds sdk.Coin
}{
"empty recipient addr": {
recipientAddress: sdk.AccAddress(""),
expErr: true,
expErrMsg: "invalid recipient address: empty address string is not allowed",
},
"no budget found": {
recipientAddress: sdk.AccAddress([]byte("acc1__________")),
expErr: true,
expErrMsg: "no budget found for recipient",
},
"claiming before start time": {
preRun: func() {
startTime := suite.ctx.BlockTime().Add(3600 * time.Second)
// Prepare the budget proposal with a future start time
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
},
recipientAddress: recipientAddr,
expErr: true,
expErrMsg: "distribution has not started yet",
},
"budget period has not passed": {
preRun: func() {
startTime := suite.ctx.BlockTime().Add(-50 * time.Second)
// Prepare the budget proposal with start time and a short period
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 1,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
},
recipientAddress: recipientAddr,
expErr: true,
expErrMsg: "budget period has not passed yet",
},
"valid claim": {
preRun: func() {
// Prepare the budget proposal with valid start time and period
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
},
recipientAddress: recipientAddr,
expErr: false,
claimableFunds: sdk.NewInt64Coin("foo", 50),
},
"double claim attempt with budget period not passed": {
preRun: func() {
// Prepare the budget proposal with valid start time and period
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
// Claim the funds once
msg := &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
suite.mockSendCoinsFromModuleToAccount(recipientAddr)
_, err = suite.msgServer.ClaimBudget(suite.ctx, msg)
suite.Require().NoError(err)
},
recipientAddress: recipientAddr,
expErr: true,
expErrMsg: "budget period has not passed yet",
},
"valid double claim attempt": {
preRun: func() {
oneMonthInSeconds := int64(30 * 24 * 60 * 60) // Approximate number of seconds in 1 month
startTimeBeforeMonth := suite.ctx.BlockTime().Add(time.Duration(-oneMonthInSeconds) * time.Second)
oneMonthPeriod := time.Duration(oneMonthInSeconds) * time.Second
// Prepare the budget proposal with valid start time and period of 1 month (in seconds)
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTimeBeforeMonth,
Tranches: 2,
Period: &oneMonthPeriod,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
// Claim the funds once
msg := &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
suite.mockSendCoinsFromModuleToAccount(recipientAddr)
_, err = suite.msgServer.ClaimBudget(suite.ctx, msg)
suite.Require().NoError(err)
// Create a new context with an updated block time to simulate a delay
newBlockTime := suite.ctx.BlockTime().Add(time.Duration(oneMonthInSeconds) * time.Second)
suite.ctx = suite.ctx.WithHeaderInfo(header.Info{
Time: newBlockTime,
})
},
recipientAddress: recipientAddr,
expErr: false,
claimableFunds: sdk.NewInt64Coin("foo", 50),
},
"budget ended for recipient": {
preRun: func() {
// Prepare the budget proposal with valid start time and period
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: &startTime,
Tranches: 2,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
// Claim the funds once
msg := &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
suite.mockSendCoinsFromModuleToAccount(recipientAddr)
_, err = suite.msgServer.ClaimBudget(suite.ctx, msg)
suite.Require().NoError(err)
// Create a new context with an updated block time to simulate a delay
newBlockTime := suite.ctx.BlockTime().Add(60 * time.Second)
suite.ctx = suite.ctx.WithHeaderInfo(header.Info{
Time: newBlockTime,
})
// Claim the funds twice
msg = &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
suite.mockSendCoinsFromModuleToAccount(recipientAddr)
_, err = suite.msgServer.ClaimBudget(suite.ctx, msg)
suite.Require().NoError(err)
},
recipientAddress: recipientAddr,
expErr: true,
expErrMsg: "budget ended for recipient",
},
}
for name, tc := range testCases {
suite.Run(name, func() {
suite.SetupTest()
if tc.preRun != nil {
tc.preRun()
}
msg := &types.MsgClaimBudget{
RecipientAddress: tc.recipientAddress.String(),
}
suite.mockSendCoinsFromModuleToAccount(tc.recipientAddress)
resp, err := suite.msgServer.ClaimBudget(suite.ctx, msg)
if tc.expErr {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.expErrMsg)
} else {
suite.Require().NoError(err)
suite.Require().Equal(tc.claimableFunds, resp.Amount)
}
})
}
}

View File

@ -11,6 +11,8 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
(*sdk.Msg)(nil),
&MsgFundCommunityPool{},
&MsgCommunityPoolSpend{},
&MsgSubmitBudgetProposal{},
&MsgClaimBudget{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)

View File

@ -1,5 +1,7 @@
package types
import "cosmossdk.io/collections"
const (
// ModuleName is the module name constant used in many places
ModuleName = "protocolpool"
@ -13,3 +15,5 @@ const (
// GovModuleName is the name of the gov module
GovModuleName = "gov"
)
var BudgetKey = collections.NewPrefix(2)

View File

@ -6,24 +6,30 @@ package types
import (
context "context"
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/gogoproto/gogoproto"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/timestamppb"
io "io"
math "math"
math_bits "math/bits"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
@ -116,9 +122,151 @@ func (m *QueryCommunityPoolResponse) GetPool() github_com_cosmos_cosmos_sdk_type
return nil
}
// QueryUnclaimedBudgetRequest is the request type for the Query/UnclaimedBudgetRequest
// RPC method.
type QueryUnclaimedBudgetRequest struct {
// address is the recipient address to query unclaimed budget amount for.
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
}
func (m *QueryUnclaimedBudgetRequest) Reset() { *m = QueryUnclaimedBudgetRequest{} }
func (m *QueryUnclaimedBudgetRequest) String() string { return proto.CompactTextString(m) }
func (*QueryUnclaimedBudgetRequest) ProtoMessage() {}
func (*QueryUnclaimedBudgetRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_51500a0a77d57843, []int{2}
}
func (m *QueryUnclaimedBudgetRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryUnclaimedBudgetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryUnclaimedBudgetRequest.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 *QueryUnclaimedBudgetRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryUnclaimedBudgetRequest.Merge(m, src)
}
func (m *QueryUnclaimedBudgetRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryUnclaimedBudgetRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryUnclaimedBudgetRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryUnclaimedBudgetRequest proto.InternalMessageInfo
func (m *QueryUnclaimedBudgetRequest) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
// QueryUnclaimedBudgetResponse is the response type for the Query/UnclaimedBudget
// RPC method.
type QueryUnclaimedBudgetResponse struct {
// total_budget is the total budget allocated to the recipient
TotalBudget *types.Coin `protobuf:"bytes,1,opt,name=total_budget,json=totalBudget,proto3" json:"total_budget,omitempty"`
// claimed_amount is the budget amount already claimed by the recipient
ClaimedAmount *types.Coin `protobuf:"bytes,2,opt,name=claimed_amount,json=claimedAmount,proto3" json:"claimed_amount,omitempty"`
// unclaimed_amount is the remaining budget amount that is unclaimed by the recipient
UnclaimedAmount *types.Coin `protobuf:"bytes,3,opt,name=unclaimed_amount,json=unclaimedAmount,proto3" json:"unclaimed_amount,omitempty"`
// next_claim_from is the next starting claim time for fund distribution.
// It represents the time when we can claim funds after the period time interval has passed.
NextClaimFrom *time.Time `protobuf:"bytes,4,opt,name=next_claim_from,json=nextClaimFrom,proto3,stdtime" json:"next_claim_from,omitempty"`
// period is the time interval for fund distribution
Period *time.Duration `protobuf:"bytes,5,opt,name=period,proto3,stdduration" json:"period,omitempty"`
// tranches_left is the number of tranches left for the amount to be distributed
TranchesLeft uint64 `protobuf:"varint,6,opt,name=tranches_left,json=tranchesLeft,proto3" json:"tranches_left,omitempty"`
}
func (m *QueryUnclaimedBudgetResponse) Reset() { *m = QueryUnclaimedBudgetResponse{} }
func (m *QueryUnclaimedBudgetResponse) String() string { return proto.CompactTextString(m) }
func (*QueryUnclaimedBudgetResponse) ProtoMessage() {}
func (*QueryUnclaimedBudgetResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_51500a0a77d57843, []int{3}
}
func (m *QueryUnclaimedBudgetResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryUnclaimedBudgetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryUnclaimedBudgetResponse.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 *QueryUnclaimedBudgetResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryUnclaimedBudgetResponse.Merge(m, src)
}
func (m *QueryUnclaimedBudgetResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryUnclaimedBudgetResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryUnclaimedBudgetResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryUnclaimedBudgetResponse proto.InternalMessageInfo
func (m *QueryUnclaimedBudgetResponse) GetTotalBudget() *types.Coin {
if m != nil {
return m.TotalBudget
}
return nil
}
func (m *QueryUnclaimedBudgetResponse) GetClaimedAmount() *types.Coin {
if m != nil {
return m.ClaimedAmount
}
return nil
}
func (m *QueryUnclaimedBudgetResponse) GetUnclaimedAmount() *types.Coin {
if m != nil {
return m.UnclaimedAmount
}
return nil
}
func (m *QueryUnclaimedBudgetResponse) GetNextClaimFrom() *time.Time {
if m != nil {
return m.NextClaimFrom
}
return nil
}
func (m *QueryUnclaimedBudgetResponse) GetPeriod() *time.Duration {
if m != nil {
return m.Period
}
return nil
}
func (m *QueryUnclaimedBudgetResponse) GetTranchesLeft() uint64 {
if m != nil {
return m.TranchesLeft
}
return 0
}
func init() {
proto.RegisterType((*QueryCommunityPoolRequest)(nil), "cosmos.protocolpool.v1.QueryCommunityPoolRequest")
proto.RegisterType((*QueryCommunityPoolResponse)(nil), "cosmos.protocolpool.v1.QueryCommunityPoolResponse")
proto.RegisterType((*QueryUnclaimedBudgetRequest)(nil), "cosmos.protocolpool.v1.QueryUnclaimedBudgetRequest")
proto.RegisterType((*QueryUnclaimedBudgetResponse)(nil), "cosmos.protocolpool.v1.QueryUnclaimedBudgetResponse")
}
func init() {
@ -126,28 +274,47 @@ func init() {
}
var fileDescriptor_51500a0a77d57843 = []byte{
// 335 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x51, 0x3f, 0x4e, 0xf3, 0x30,
0x14, 0x8f, 0xbf, 0x0f, 0x18, 0x82, 0x58, 0x22, 0x84, 0x20, 0x54, 0x2e, 0x64, 0x40, 0x95, 0x10,
0x7e, 0x4a, 0x3b, 0xb2, 0xb5, 0x1c, 0x00, 0x3a, 0xb2, 0xa0, 0x24, 0xb5, 0x82, 0xd5, 0xc4, 0x2f,
0xad, 0x9d, 0x8a, 0xae, 0x70, 0x01, 0x24, 0xee, 0xc0, 0xc0, 0xc4, 0x31, 0x3a, 0x56, 0x62, 0x61,
0x02, 0xd4, 0x72, 0x10, 0x94, 0x38, 0x95, 0xa8, 0xd4, 0x0e, 0x4c, 0xb6, 0x7e, 0xef, 0xfd, 0xfe,
0xd9, 0xb6, 0x17, 0xa1, 0x4a, 0x51, 0x41, 0x36, 0x44, 0x8d, 0x11, 0x26, 0x19, 0x62, 0x02, 0x23,
0x1f, 0x06, 0x39, 0x1f, 0x8e, 0x59, 0x89, 0x3a, 0x7b, 0x66, 0x87, 0xfd, 0xde, 0x61, 0x23, 0xdf,
0xdd, 0x8d, 0x31, 0xc6, 0x12, 0x84, 0xe2, 0x66, 0xe6, 0x6e, 0x2d, 0x46, 0x8c, 0x13, 0x0e, 0x41,
0x26, 0x20, 0x90, 0x12, 0x75, 0xa0, 0x05, 0xca, 0x8a, 0xed, 0xd2, 0xca, 0x2f, 0x0c, 0x14, 0x87,
0x91, 0x1f, 0x72, 0x1d, 0xf8, 0x10, 0xa1, 0x90, 0x66, 0xee, 0x1d, 0xda, 0x07, 0x57, 0x85, 0x75,
0x07, 0xd3, 0x34, 0x97, 0x42, 0x8f, 0x2f, 0x11, 0x93, 0x2e, 0x1f, 0xe4, 0x5c, 0x69, 0xef, 0x81,
0xd8, 0xee, 0xaa, 0xa9, 0xca, 0x50, 0x2a, 0xee, 0x70, 0x7b, 0xa3, 0x88, 0xb6, 0x4f, 0x8e, 0xfe,
0x37, 0xb6, 0x9b, 0x35, 0x56, 0xc5, 0x2e, 0xac, 0x58, 0x65, 0xc5, 0x2e, 0x78, 0xd4, 0x41, 0x21,
0xdb, 0xad, 0xc9, 0x47, 0xdd, 0x7a, 0xf9, 0xac, 0x9f, 0xc6, 0x42, 0xdf, 0xe6, 0x21, 0x8b, 0x30,
0x85, 0x2a, 0x9a, 0x39, 0xce, 0x54, 0xaf, 0x0f, 0x7a, 0x9c, 0x71, 0xb5, 0xe0, 0xa8, 0x6e, 0x29,
0xdf, 0x7c, 0x25, 0xf6, 0x66, 0x99, 0xc2, 0x79, 0x26, 0xf6, 0xce, 0x52, 0x14, 0xc7, 0x67, 0xab,
0xdf, 0x8a, 0xad, 0x2d, 0xe5, 0x36, 0xff, 0x42, 0x31, 0x4d, 0x3d, 0x76, 0xff, 0xf6, 0xfd, 0xf4,
0xaf, 0xe1, 0x9c, 0xc0, 0x9a, 0xef, 0x8b, 0x16, 0xb4, 0x9b, 0x02, 0x69, 0x9f, 0x4f, 0x66, 0x94,
0x4c, 0x67, 0x94, 0x7c, 0xcd, 0x28, 0x79, 0x9c, 0x53, 0x6b, 0x3a, 0xa7, 0xd6, 0xfb, 0x9c, 0x5a,
0xd7, 0xc7, 0x46, 0x40, 0xf5, 0xfa, 0x4c, 0x20, 0xdc, 0x2d, 0x0b, 0x95, 0xf5, 0xc3, 0xad, 0x12,
0x6b, 0xfd, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xc7, 0xae, 0xa2, 0x2b, 0x02, 0x00, 0x00,
// 630 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x3f, 0x4f, 0x14, 0x41,
0x18, 0xc6, 0x6f, 0xe1, 0xc0, 0x38, 0x70, 0x62, 0x26, 0xc4, 0x2c, 0x0b, 0xd9, 0xc3, 0x33, 0x31,
0x97, 0x18, 0x66, 0x72, 0x07, 0x89, 0x89, 0x5a, 0xc8, 0x41, 0x8c, 0x85, 0x85, 0x9c, 0xda, 0xd8,
0x6c, 0xf6, 0xcf, 0xdc, 0xb2, 0x61, 0x77, 0xde, 0x65, 0x67, 0x96, 0x40, 0x8c, 0x8d, 0xb6, 0x16,
0x24, 0x36, 0x7e, 0x02, 0x0b, 0x6b, 0x0b, 0x3f, 0x02, 0x25, 0xd1, 0xc6, 0x4a, 0x0c, 0xd8, 0xf9,
0x25, 0xcc, 0xce, 0xce, 0x2a, 0x5c, 0x0e, 0x09, 0xd5, 0xdd, 0xbe, 0xef, 0xfb, 0xfc, 0xe6, 0x79,
0x33, 0xcf, 0xa0, 0x96, 0x0f, 0x22, 0x01, 0x41, 0xd3, 0x0c, 0x24, 0xf8, 0x10, 0xa7, 0x00, 0x31,
0xdd, 0xe9, 0xd0, 0xed, 0x9c, 0x65, 0x7b, 0x44, 0x55, 0xf1, 0x8d, 0x72, 0x86, 0x9c, 0x9e, 0x21,
0x3b, 0x1d, 0x6b, 0x36, 0x84, 0x10, 0x54, 0x91, 0x16, 0xff, 0xca, 0xbe, 0xb5, 0x10, 0x02, 0x84,
0x31, 0xa3, 0x6e, 0x1a, 0x51, 0x97, 0x73, 0x90, 0xae, 0x8c, 0x80, 0x6b, 0xb5, 0x65, 0xeb, 0xf3,
0x3c, 0x57, 0x30, 0xba, 0xd3, 0xf1, 0x98, 0x74, 0x3b, 0xd4, 0x87, 0x88, 0xeb, 0xfe, 0x5c, 0xd9,
0x77, 0x4a, 0xec, 0xe9, 0x83, 0xad, 0xa6, 0x06, 0xab, 0x2f, 0x2f, 0x1f, 0x50, 0x19, 0x25, 0x4c,
0x48, 0x37, 0x49, 0x2b, 0xf6, 0xf0, 0x40, 0x90, 0x67, 0xea, 0xf0, 0xb2, 0xdf, 0x9a, 0x47, 0x73,
0x1b, 0xc5, 0x5a, 0x6b, 0x90, 0x24, 0x39, 0x8f, 0xe4, 0xde, 0x53, 0x80, 0xb8, 0xcf, 0xb6, 0x73,
0x26, 0x64, 0xeb, 0xad, 0x81, 0xac, 0x51, 0x5d, 0x91, 0x02, 0x17, 0x0c, 0x33, 0x54, 0x2f, 0xd6,
0x36, 0x8d, 0xc5, 0xf1, 0xf6, 0x54, 0x77, 0x81, 0x68, 0x67, 0xc5, 0x1a, 0x44, 0xaf, 0x41, 0xd6,
0x99, 0xbf, 0x06, 0x11, 0xef, 0x2d, 0x1f, 0xfc, 0x68, 0xd6, 0x3e, 0x1d, 0x35, 0xef, 0x84, 0x91,
0xdc, 0xcc, 0x3d, 0xe2, 0x43, 0xa2, 0x37, 0xd1, 0x3f, 0x4b, 0x22, 0xd8, 0xa2, 0x72, 0x2f, 0x65,
0xa2, 0xd2, 0x88, 0xbe, 0xc2, 0xb7, 0x36, 0xd0, 0xbc, 0x32, 0xf1, 0x82, 0xfb, 0xb1, 0x1b, 0x25,
0x2c, 0xe8, 0xe5, 0x41, 0xc8, 0xa4, 0x36, 0x89, 0xbb, 0xe8, 0x8a, 0x1b, 0x04, 0x19, 0x13, 0xc2,
0x34, 0x16, 0x8d, 0xf6, 0xd5, 0x9e, 0xf9, 0xf5, 0xf3, 0xd2, 0xac, 0xf6, 0xb2, 0x5a, 0x76, 0x9e,
0xc9, 0x2c, 0xe2, 0x61, 0xbf, 0x1a, 0x6c, 0xbd, 0x1b, 0x47, 0x0b, 0xa3, 0x99, 0x7a, 0xb5, 0x07,
0x68, 0x5a, 0x82, 0x74, 0x63, 0xc7, 0x53, 0x75, 0x45, 0x9e, 0xea, 0xce, 0x8d, 0x5c, 0xb1, 0xf0,
0xda, 0x9f, 0x52, 0xe3, 0x25, 0x05, 0x3f, 0x44, 0xd7, 0x34, 0xd6, 0x71, 0x13, 0xc8, 0xb9, 0x34,
0xc7, 0x2e, 0xd2, 0x37, 0xb4, 0x60, 0x55, 0xcd, 0xe3, 0x75, 0x74, 0x3d, 0xe7, 0x43, 0x8c, 0xf1,
0x8b, 0x18, 0x33, 0x7f, 0x25, 0x9a, 0xf2, 0x18, 0xcd, 0x70, 0xb6, 0x2b, 0x1d, 0x55, 0x75, 0x06,
0x19, 0x24, 0x66, 0x5d, 0x41, 0x2c, 0x52, 0xc6, 0x82, 0x54, 0xb1, 0x20, 0xcf, 0xab, 0xdc, 0xf4,
0xea, 0xfb, 0x47, 0x4d, 0xa3, 0xdf, 0x28, 0x84, 0x6b, 0x85, 0xee, 0x51, 0x06, 0x09, 0xbe, 0x8b,
0x26, 0x53, 0x96, 0x45, 0x10, 0x98, 0x13, 0xda, 0xc5, 0x30, 0x60, 0x5d, 0xe7, 0xaa, 0x57, 0xff,
0x50, 0xe8, 0xf5, 0x38, 0xbe, 0x85, 0x1a, 0x32, 0x73, 0xb9, 0xbf, 0xc9, 0x84, 0x13, 0xb3, 0x81,
0x34, 0x27, 0x17, 0x8d, 0x76, 0xbd, 0x3f, 0x5d, 0x15, 0x9f, 0xb0, 0x81, 0xec, 0xfe, 0x1e, 0x43,
0x13, 0xea, 0x3a, 0xf0, 0x47, 0x03, 0x35, 0xce, 0x84, 0x0d, 0x77, 0xc8, 0xe8, 0x97, 0x46, 0xce,
0x8d, 0xad, 0xd5, 0xbd, 0x8c, 0xa4, 0xbc, 0xf0, 0x16, 0x79, 0xf3, 0xed, 0xd7, 0xfb, 0xb1, 0x36,
0xbe, 0x4d, 0xcf, 0x79, 0xfc, 0x7e, 0x25, 0x73, 0x8a, 0x0a, 0xfe, 0x62, 0xa0, 0x99, 0xa1, 0xf0,
0xe0, 0xe5, 0xff, 0x9e, 0x3b, 0x3a, 0xbe, 0xd6, 0xca, 0xe5, 0x44, 0xda, 0xee, 0x3d, 0x65, 0x77,
0x05, 0x77, 0xcf, 0xb3, 0xfb, 0x2f, 0x3d, 0x65, 0x82, 0xe9, 0x2b, 0x9d, 0xfd, 0xd7, 0xbd, 0xfb,
0x07, 0xc7, 0xb6, 0x71, 0x78, 0x6c, 0x1b, 0x3f, 0x8f, 0x6d, 0x63, 0xff, 0xc4, 0xae, 0x1d, 0x9e,
0xd8, 0xb5, 0xef, 0x27, 0x76, 0xed, 0xe5, 0xcd, 0x12, 0x26, 0x82, 0x2d, 0x12, 0x01, 0xdd, 0x3d,
0x0b, 0x55, 0x6f, 0xd3, 0x9b, 0x54, 0xb5, 0xe5, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5a, 0xe5,
0xc6, 0x53, 0x24, 0x05, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -164,6 +331,8 @@ const _ = grpc.SupportPackageIsVersion4
type QueryClient interface {
// CommunityPool queries the community pool coins.
CommunityPool(ctx context.Context, in *QueryCommunityPoolRequest, opts ...grpc.CallOption) (*QueryCommunityPoolResponse, error)
// UnclaimedBudget queries the remaining budget left to be claimed and it gives overall budget allocation view.
UnclaimedBudget(ctx context.Context, in *QueryUnclaimedBudgetRequest, opts ...grpc.CallOption) (*QueryUnclaimedBudgetResponse, error)
}
type queryClient struct {
@ -183,10 +352,21 @@ func (c *queryClient) CommunityPool(ctx context.Context, in *QueryCommunityPoolR
return out, nil
}
func (c *queryClient) UnclaimedBudget(ctx context.Context, in *QueryUnclaimedBudgetRequest, opts ...grpc.CallOption) (*QueryUnclaimedBudgetResponse, error) {
out := new(QueryUnclaimedBudgetResponse)
err := c.cc.Invoke(ctx, "/cosmos.protocolpool.v1.Query/UnclaimedBudget", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// CommunityPool queries the community pool coins.
CommunityPool(context.Context, *QueryCommunityPoolRequest) (*QueryCommunityPoolResponse, error)
// UnclaimedBudget queries the remaining budget left to be claimed and it gives overall budget allocation view.
UnclaimedBudget(context.Context, *QueryUnclaimedBudgetRequest) (*QueryUnclaimedBudgetResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
@ -196,6 +376,9 @@ type UnimplementedQueryServer struct {
func (*UnimplementedQueryServer) CommunityPool(ctx context.Context, req *QueryCommunityPoolRequest) (*QueryCommunityPoolResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CommunityPool not implemented")
}
func (*UnimplementedQueryServer) UnclaimedBudget(ctx context.Context, req *QueryUnclaimedBudgetRequest) (*QueryUnclaimedBudgetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnclaimedBudget not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
@ -219,6 +402,24 @@ func _Query_CommunityPool_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler)
}
func _Query_UnclaimedBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryUnclaimedBudgetRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).UnclaimedBudget(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.protocolpool.v1.Query/UnclaimedBudget",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).UnclaimedBudget(ctx, req.(*QueryUnclaimedBudgetRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.protocolpool.v1.Query",
HandlerType: (*QueryServer)(nil),
@ -227,6 +428,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{
MethodName: "CommunityPool",
Handler: _Query_CommunityPool_Handler,
},
{
MethodName: "UnclaimedBudget",
Handler: _Query_UnclaimedBudget_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/protocolpool/v1/query.proto",
@ -292,6 +497,120 @@ func (m *QueryCommunityPoolResponse) MarshalToSizedBuffer(dAtA []byte) (int, err
return len(dAtA) - i, nil
}
func (m *QueryUnclaimedBudgetRequest) 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 *QueryUnclaimedBudgetRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryUnclaimedBudgetRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Address) > 0 {
i -= len(m.Address)
copy(dAtA[i:], m.Address)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Address)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *QueryUnclaimedBudgetResponse) 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 *QueryUnclaimedBudgetResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryUnclaimedBudgetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.TranchesLeft != 0 {
i = encodeVarintQuery(dAtA, i, uint64(m.TranchesLeft))
i--
dAtA[i] = 0x30
}
if m.Period != nil {
n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(*m.Period, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(*m.Period):])
if err1 != nil {
return 0, err1
}
i -= n1
i = encodeVarintQuery(dAtA, i, uint64(n1))
i--
dAtA[i] = 0x2a
}
if m.NextClaimFrom != nil {
n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.NextClaimFrom, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NextClaimFrom):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintQuery(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x22
}
if m.UnclaimedAmount != nil {
{
size, err := m.UnclaimedAmount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
if m.ClaimedAmount != nil {
{
size, err := m.ClaimedAmount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if m.TotalBudget != nil {
{
size, err := m.TotalBudget.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
@ -327,6 +646,51 @@ func (m *QueryCommunityPoolResponse) Size() (n int) {
return n
}
func (m *QueryUnclaimedBudgetRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Address)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func (m *QueryUnclaimedBudgetResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.TotalBudget != nil {
l = m.TotalBudget.Size()
n += 1 + l + sovQuery(uint64(l))
}
if m.ClaimedAmount != nil {
l = m.ClaimedAmount.Size()
n += 1 + l + sovQuery(uint64(l))
}
if m.UnclaimedAmount != nil {
l = m.UnclaimedAmount.Size()
n += 1 + l + sovQuery(uint64(l))
}
if m.NextClaimFrom != nil {
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NextClaimFrom)
n += 1 + l + sovQuery(uint64(l))
}
if m.Period != nil {
l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(*m.Period)
n += 1 + l + sovQuery(uint64(l))
}
if m.TranchesLeft != 0 {
n += 1 + sovQuery(uint64(m.TranchesLeft))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -467,6 +831,337 @@ func (m *QueryCommunityPoolResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *QueryUnclaimedBudgetRequest) 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: QueryUnclaimedBudgetRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryUnclaimedBudgetRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
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 ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Address = string(dAtA[iNdEx:postIndex])
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 (m *QueryUnclaimedBudgetResponse) 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: QueryUnclaimedBudgetResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryUnclaimedBudgetResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TotalBudget", 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.TotalBudget == nil {
m.TotalBudget = &types.Coin{}
}
if err := m.TotalBudget.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimedAmount", 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.ClaimedAmount == nil {
m.ClaimedAmount = &types.Coin{}
}
if err := m.ClaimedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field UnclaimedAmount", 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.UnclaimedAmount == nil {
m.UnclaimedAmount = &types.Coin{}
}
if err := m.UnclaimedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field NextClaimFrom", 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.NextClaimFrom == nil {
m.NextClaimFrom = new(time.Time)
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.NextClaimFrom, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Period", 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.Period == nil {
m.Period = new(time.Duration)
}
if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(m.Period, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TranchesLeft", wireType)
}
m.TranchesLeft = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TranchesLeft |= 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 skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -51,6 +51,60 @@ func local_request_Query_CommunityPool_0(ctx context.Context, marshaler runtime.
}
func request_Query_UnclaimedBudget_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryUnclaimedBudgetRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address")
}
protoReq.Address, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err)
}
msg, err := client.UnclaimedBudget(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_UnclaimedBudget_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryUnclaimedBudgetRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address")
}
protoReq.Address, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err)
}
msg, err := server.UnclaimedBudget(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.
@ -80,6 +134,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
})
mux.Handle("GET", pattern_Query_UnclaimedBudget_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_UnclaimedBudget_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_UnclaimedBudget_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -141,13 +218,37 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
})
mux.Handle("GET", pattern_Query_UnclaimedBudget_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_UnclaimedBudget_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_UnclaimedBudget_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_CommunityPool_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "protocolpool", "v1", "community_pool"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_UnclaimedBudget_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "protocolpool", "v1", "unclaimed_budget", "address"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_CommunityPool_0 = runtime.ForwardResponseMessage
forward_Query_UnclaimedBudget_0 = runtime.ForwardResponseMessage
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,718 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/protocolpool/v1/types.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/gogoproto/gogoproto"
proto "github.com/cosmos/gogoproto/proto"
github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/timestamppb"
io "io"
math "math"
math_bits "math/bits"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// Budget defines the fields of a budget proposal.
type Budget struct {
// recipient_address is the address of the recipient who can claim the budget.
RecipientAddress string `protobuf:"bytes,1,opt,name=recipient_address,json=recipientAddress,proto3" json:"recipient_address,omitempty"`
// total_budget is the total amount allocated for the budget.
TotalBudget *types.Coin `protobuf:"bytes,2,opt,name=total_budget,json=totalBudget,proto3" json:"total_budget,omitempty"`
// claimed_amount is the total amount claimed from the total budget amount requested.
ClaimedAmount *types.Coin `protobuf:"bytes,3,opt,name=claimed_amount,json=claimedAmount,proto3" json:"claimed_amount,omitempty"`
// start_time is the time when the budget becomes claimable.
StartTime *time.Time `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time,omitempty"`
// next_claim_from is the time when the budget was last successfully claimed or distributed.
// It is used to track the next starting claim time for fund distribution. If set, it cannot be less than start_time.
NextClaimFrom *time.Time `protobuf:"bytes,5,opt,name=next_claim_from,json=nextClaimFrom,proto3,stdtime" json:"next_claim_from,omitempty"`
// tranches is the number of times the total budget amount is to be distributed.
Tranches uint64 `protobuf:"varint,6,opt,name=tranches,proto3" json:"tranches,omitempty"`
// tranches_left is the number of tranches left for the amount to be distributed.
TranchesLeft uint64 `protobuf:"varint,7,opt,name=tranches_left,json=tranchesLeft,proto3" json:"tranches_left,omitempty"`
// Period is the time interval(number of seconds) at which funds distribution should be performed.
// For example, if a period is set to 3600, it represents an action that
// should occur every hour (3600 seconds).
Period *time.Duration `protobuf:"bytes,8,opt,name=period,proto3,stdduration" json:"period,omitempty"`
}
func (m *Budget) Reset() { *m = Budget{} }
func (m *Budget) String() string { return proto.CompactTextString(m) }
func (*Budget) ProtoMessage() {}
func (*Budget) Descriptor() ([]byte, []int) {
return fileDescriptor_c1b7d0ea246d7f44, []int{0}
}
func (m *Budget) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Budget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Budget.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 *Budget) XXX_Merge(src proto.Message) {
xxx_messageInfo_Budget.Merge(m, src)
}
func (m *Budget) XXX_Size() int {
return m.Size()
}
func (m *Budget) XXX_DiscardUnknown() {
xxx_messageInfo_Budget.DiscardUnknown(m)
}
var xxx_messageInfo_Budget proto.InternalMessageInfo
func (m *Budget) GetRecipientAddress() string {
if m != nil {
return m.RecipientAddress
}
return ""
}
func (m *Budget) GetTotalBudget() *types.Coin {
if m != nil {
return m.TotalBudget
}
return nil
}
func (m *Budget) GetClaimedAmount() *types.Coin {
if m != nil {
return m.ClaimedAmount
}
return nil
}
func (m *Budget) GetStartTime() *time.Time {
if m != nil {
return m.StartTime
}
return nil
}
func (m *Budget) GetNextClaimFrom() *time.Time {
if m != nil {
return m.NextClaimFrom
}
return nil
}
func (m *Budget) GetTranches() uint64 {
if m != nil {
return m.Tranches
}
return 0
}
func (m *Budget) GetTranchesLeft() uint64 {
if m != nil {
return m.TranchesLeft
}
return 0
}
func (m *Budget) GetPeriod() *time.Duration {
if m != nil {
return m.Period
}
return nil
}
func init() {
proto.RegisterType((*Budget)(nil), "cosmos.protocolpool.v1.Budget")
}
func init() {
proto.RegisterFile("cosmos/protocolpool/v1/types.proto", fileDescriptor_c1b7d0ea246d7f44)
}
var fileDescriptor_c1b7d0ea246d7f44 = []byte{
// 444 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x3f, 0x6f, 0xd4, 0x30,
0x1c, 0xbd, 0xd0, 0xe3, 0x68, 0xdd, 0x1e, 0x7f, 0xa2, 0x0a, 0xb9, 0x19, 0xd2, 0xa3, 0x2c, 0xb7,
0xe0, 0xe8, 0x60, 0x60, 0x00, 0x09, 0x9a, 0x02, 0x62, 0x60, 0x3a, 0x98, 0x58, 0x2c, 0x27, 0xf1,
0x05, 0x8b, 0x24, 0xbf, 0xc8, 0xfe, 0xdd, 0xa9, 0x7c, 0x8b, 0x8e, 0x7c, 0x10, 0x3e, 0x04, 0x63,
0x85, 0x18, 0xd8, 0x40, 0x77, 0x5f, 0x04, 0xc5, 0x76, 0xaa, 0xd2, 0x85, 0x6e, 0xce, 0xfb, 0xbd,
0xf7, 0xf2, 0xfc, 0xfc, 0x23, 0x47, 0x39, 0x98, 0x1a, 0x4c, 0xd2, 0x6a, 0x40, 0xc8, 0xa1, 0x6a,
0x01, 0xaa, 0x64, 0x35, 0x4b, 0xf0, 0x4b, 0x2b, 0x0d, 0xb3, 0x68, 0x78, 0xdf, 0x71, 0xd8, 0x65,
0x0e, 0x5b, 0xcd, 0xa2, 0xfd, 0x12, 0x4a, 0xb0, 0x60, 0xd2, 0x9d, 0xdc, 0x3c, 0x3a, 0x70, 0x6c,
0xee, 0x06, 0x97, 0xa5, 0x51, 0xec, 0x7f, 0x96, 0x09, 0x23, 0x93, 0xd5, 0x2c, 0x93, 0x28, 0x66,
0x49, 0x0e, 0xaa, 0xf1, 0xf3, 0xc3, 0x12, 0xa0, 0xac, 0xa4, 0x0b, 0x93, 0x2d, 0x17, 0x09, 0xaa,
0x5a, 0x1a, 0x14, 0x75, 0xdb, 0x1b, 0x5c, 0x25, 0x14, 0x4b, 0x2d, 0x50, 0x81, 0x37, 0x38, 0xfa,
0xb9, 0x45, 0x46, 0xe9, 0xb2, 0x28, 0x25, 0x86, 0xaf, 0xc9, 0x3d, 0x2d, 0x73, 0xd5, 0x2a, 0xd9,
0x20, 0x17, 0x45, 0xa1, 0xa5, 0x31, 0x34, 0x98, 0x04, 0xd3, 0x9d, 0x94, 0xfe, 0xf8, 0xf6, 0x68,
0xdf, 0x07, 0x3b, 0x76, 0x93, 0xf7, 0xa8, 0x55, 0x53, 0xce, 0xef, 0x5e, 0x48, 0x3c, 0x1e, 0x3e,
0x27, 0x7b, 0x08, 0x28, 0x2a, 0x9e, 0x59, 0x5b, 0x7a, 0x63, 0x12, 0x4c, 0x77, 0x1f, 0x1f, 0x30,
0x2f, 0xef, 0x6e, 0xc2, 0xfc, 0x4d, 0xd8, 0x09, 0xa8, 0x66, 0xbe, 0x6b, 0xe9, 0x3e, 0xc4, 0x4b,
0x72, 0x3b, 0xaf, 0x84, 0xaa, 0x65, 0xc1, 0x45, 0x0d, 0xcb, 0x06, 0xe9, 0xd6, 0xff, 0xf4, 0x63,
0x2f, 0x38, 0xb6, 0xfc, 0xf0, 0x05, 0x21, 0x06, 0x85, 0x46, 0xde, 0x55, 0x41, 0x87, 0x56, 0x1d,
0x31, 0x57, 0x03, 0xeb, 0x6b, 0x60, 0x1f, 0xfa, 0x9e, 0xd2, 0xe1, 0xd9, 0xef, 0xc3, 0x60, 0xbe,
0x63, 0x35, 0x1d, 0x1a, 0xbe, 0x25, 0x77, 0x1a, 0x79, 0x8a, 0xdc, 0xda, 0xf2, 0x85, 0x86, 0x9a,
0xde, 0xbc, 0xa6, 0xcb, 0xb8, 0x13, 0x9e, 0x74, 0xba, 0x37, 0x1a, 0xea, 0x30, 0x22, 0xdb, 0xa8,
0x45, 0x93, 0x7f, 0x92, 0x86, 0x8e, 0x26, 0xc1, 0x74, 0x38, 0xbf, 0xf8, 0x0e, 0x1f, 0x92, 0x71,
0x7f, 0xe6, 0x95, 0x5c, 0x20, 0xbd, 0x65, 0x09, 0x7b, 0x3d, 0xf8, 0x4e, 0x2e, 0x30, 0x7c, 0x4a,
0x46, 0xad, 0xd4, 0x0a, 0x0a, 0xba, 0xed, 0x5b, 0xb8, 0x9a, 0xe0, 0x95, 0x7f, 0xce, 0x74, 0xf8,
0xb5, 0x0b, 0xe0, 0xe9, 0xe9, 0xb3, 0xef, 0xeb, 0x38, 0x38, 0x5f, 0xc7, 0xc1, 0x9f, 0x75, 0x1c,
0x9c, 0x6d, 0xe2, 0xc1, 0xf9, 0x26, 0x1e, 0xfc, 0xda, 0xc4, 0x83, 0x8f, 0x0f, 0x5c, 0x8f, 0xa6,
0xf8, 0xcc, 0x14, 0x24, 0xa7, 0xff, 0xae, 0xb1, 0xdd, 0xe1, 0x6c, 0x64, 0xb1, 0x27, 0x7f, 0x03,
0x00, 0x00, 0xff, 0xff, 0x07, 0x16, 0x5b, 0x67, 0xea, 0x02, 0x00, 0x00,
}
func (m *Budget) 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 *Budget) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Budget) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Period != nil {
n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(*m.Period, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(*m.Period):])
if err1 != nil {
return 0, err1
}
i -= n1
i = encodeVarintTypes(dAtA, i, uint64(n1))
i--
dAtA[i] = 0x42
}
if m.TranchesLeft != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.TranchesLeft))
i--
dAtA[i] = 0x38
}
if m.Tranches != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.Tranches))
i--
dAtA[i] = 0x30
}
if m.NextClaimFrom != nil {
n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.NextClaimFrom, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NextClaimFrom):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintTypes(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x2a
}
if m.StartTime != nil {
n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.StartTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.StartTime):])
if err3 != nil {
return 0, err3
}
i -= n3
i = encodeVarintTypes(dAtA, i, uint64(n3))
i--
dAtA[i] = 0x22
}
if m.ClaimedAmount != nil {
{
size, err := m.ClaimedAmount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
if m.TotalBudget != nil {
{
size, err := m.TotalBudget.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.RecipientAddress) > 0 {
i -= len(m.RecipientAddress)
copy(dAtA[i:], m.RecipientAddress)
i = encodeVarintTypes(dAtA, i, uint64(len(m.RecipientAddress)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintTypes(dAtA []byte, offset int, v uint64) int {
offset -= sovTypes(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Budget) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.RecipientAddress)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.TotalBudget != nil {
l = m.TotalBudget.Size()
n += 1 + l + sovTypes(uint64(l))
}
if m.ClaimedAmount != nil {
l = m.ClaimedAmount.Size()
n += 1 + l + sovTypes(uint64(l))
}
if m.StartTime != nil {
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.StartTime)
n += 1 + l + sovTypes(uint64(l))
}
if m.NextClaimFrom != nil {
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.NextClaimFrom)
n += 1 + l + sovTypes(uint64(l))
}
if m.Tranches != 0 {
n += 1 + sovTypes(uint64(m.Tranches))
}
if m.TranchesLeft != 0 {
n += 1 + sovTypes(uint64(m.TranchesLeft))
}
if m.Period != nil {
l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(*m.Period)
n += 1 + l + sovTypes(uint64(l))
}
return n
}
func sovTypes(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozTypes(x uint64) (n int) {
return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Budget) 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 ErrIntOverflowTypes
}
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: Budget: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Budget: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RecipientAddress", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
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 ErrInvalidLengthTypes
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RecipientAddress = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TotalBudget", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.TotalBudget == nil {
m.TotalBudget = &types.Coin{}
}
if err := m.TotalBudget.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimedAmount", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.ClaimedAmount == nil {
m.ClaimedAmount = &types.Coin{}
}
if err := m.ClaimedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.StartTime == nil {
m.StartTime = new(time.Time)
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.StartTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field NextClaimFrom", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.NextClaimFrom == nil {
m.NextClaimFrom = new(time.Time)
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.NextClaimFrom, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Tranches", wireType)
}
m.Tranches = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Tranches |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TranchesLeft", wireType)
}
m.TranchesLeft = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TranchesLeft |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Period", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Period == nil {
m.Period = new(time.Duration)
}
if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(m.Period, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTypes
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTypes(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTypes
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTypes
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTypes
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthTypes
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupTypes
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthTypes
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group")
)