Skip to content

Commit

Permalink
Merge branch 'develop' into localnet-2
Browse files Browse the repository at this point in the history
  • Loading branch information
lumtis authored May 29, 2022
2 parents 93cba2d + b6b4eaf commit 26cec92
Show file tree
Hide file tree
Showing 7 changed files with 865 additions and 101 deletions.
25 changes: 24 additions & 1 deletion proto/campaign/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";
package tendermint.spn.campaign;

import "google/api/annotations.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "campaign/campaign_chains.proto";
Expand Down Expand Up @@ -32,6 +33,11 @@ service Query {
option (google.api.http).get = "/tendermint/spn/campaign/campaign_chains/{campaignID}";
}

// Queries a list of SpecialAllocationsBalance items.
rpc SpecialAllocationsBalance(QuerySpecialAllocationsBalanceRequest) returns (QuerySpecialAllocationsBalanceResponse) {
option (google.api.http).get = "/tendermint/spn/campaign/special_allocations_balance/{campaignID}";
}

// Queries a mainnetAccount by index.
rpc MainnetAccount(QueryGetMainnetAccountRequest) returns (QueryGetMainnetAccountResponse) {
option (google.api.http).get = "/tendermint/spn/campaign/mainnet_account/{campaignID}/{address}";
Expand Down Expand Up @@ -87,7 +93,7 @@ service Query {
option (google.api.http).get = "/tendermint/spn/campaign/auctions_of_campaign/{campaignID}";
}

// this line is used by starport scaffolding # 2
// this line is used by starport scaffolding # 2
}

message QueryGetCampaignRequest {
Expand Down Expand Up @@ -115,6 +121,23 @@ message QueryGetCampaignChainsResponse {
CampaignChains campaignChains = 1 [(gogoproto.nullable) = false];
}

message QuerySpecialAllocationsBalanceRequest {
uint64 campaignID = 1;
}

message QuerySpecialAllocationsBalanceResponse {
repeated cosmos.base.v1beta1.Coin genesisDistribution = 1 [
(gogoproto.nullable) = false,
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin",
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
repeated cosmos.base.v1beta1.Coin claimableAirdrop = 2 [
(gogoproto.nullable) = false,
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin",
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

message QueryGetMainnetAccountRequest {
uint64 campaignID = 1;
string address = 2;
Expand Down
1 change: 1 addition & 0 deletions x/campaign/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command {
CmdShowCampaign(),
CmdListCampaign(),
CmdShowCampaignChains(),
CmdSpecialAllocationsBalance(),
CmdShowMainnetAccount(),
CmdListMainnetAccount(),
CmdShowMainnetAccountBalance(),
Expand Down
46 changes: 46 additions & 0 deletions x/campaign/client/cli/query_special_allocations_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cast"
"github.com/spf13/cobra"

"github.com/tendermint/spn/x/campaign/types"
)

func CmdSpecialAllocationsBalance() *cobra.Command {
cmd := &cobra.Command{
Use: "special-allocations-balance [campaign-id]",
Short: "query the coin balance for special allocations",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) (err error) {
reqCampaignID, err := cast.ToUint64E(args[0])
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

params := &types.QuerySpecialAllocationsBalanceRequest{
CampaignID: reqCampaignID,
}

res, err := queryClient.SpecialAllocationsBalance(cmd.Context(), params)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
50 changes: 50 additions & 0 deletions x/campaign/keeper/grpc_special_allocations_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/tendermint/spn/x/campaign/types"
)

func (k Keeper) SpecialAllocationsBalance(
goCtx context.Context,
req *types.QuerySpecialAllocationsBalanceRequest,
) (*types.QuerySpecialAllocationsBalanceResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(goCtx)

// get the campaign
totalShareNumber := k.GetTotalShares(ctx)
campaign, found := k.GetCampaign(ctx, req.CampaignID)
if !found {
return nil, status.Error(codes.NotFound, "not found")
}

// calculate special allocations balance from total supply
genesisDistribution, err := campaign.SpecialAllocations.GenesisDistribution.CoinsFromTotalSupply(
campaign.TotalSupply,
totalShareNumber,
)
if err != nil {
return nil, status.Errorf(codes.Internal, "genesis distribution can't be calculated: %s", err.Error())
}
claimableAirdrop, err := campaign.SpecialAllocations.ClaimableAirdrop.CoinsFromTotalSupply(
campaign.TotalSupply,
totalShareNumber,
)
if err != nil {
return nil, status.Errorf(codes.Internal, "claimable airdrop can't be calculated: %s", err.Error())
}

return &types.QuerySpecialAllocationsBalanceResponse{
GenesisDistribution: genesisDistribution,
ClaimableAirdrop: claimableAirdrop,
}, nil
}
93 changes: 93 additions & 0 deletions x/campaign/keeper/grpc_special_allocations_balance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package keeper_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

tc "github.com/tendermint/spn/testutil/constructor"
testkeeper "github.com/tendermint/spn/testutil/keeper"
"github.com/tendermint/spn/testutil/sample"
"github.com/tendermint/spn/x/campaign/types"
)

func TestSpecialAllocationsBalance(t *testing.T) {
var (
ctx, tk, _ = testkeeper.NewTestSetup(t)
wctx = sdk.WrapSDKContext(ctx)

campaignID = uint64(1)
campaignIDInvalidGenesisDistribution = uint64(2)
campaignIDInvalidClaimableAirdrop = uint64(3)
)

tk.CampaignKeeper.SetTotalShares(ctx, 100)

// initialize campaigns
setCampaign := func(campaignID uint64, genesisDistribution, claimableAirdrop types.Shares) {
campaign := sample.Campaign(r, campaignID)
campaign.TotalSupply = tc.Coins(t, "1000foo,1000bar,1000baz")
campaign.SpecialAllocations = types.NewSpecialAllocations(
genesisDistribution,
claimableAirdrop,
)
campaign.AllocatedShares = tc.Shares(t, "100foo,100bar,100baz,100bam")
tk.CampaignKeeper.SetCampaign(ctx, campaign)
}
setCampaign(campaignID,
tc.Shares(t, "50foo,20bar,30bam"),
tc.Shares(t, "50foo,100baz,40bam"),
)
setCampaign(campaignIDInvalidGenesisDistribution,
tc.Shares(t, "101foo"),
tc.Shares(t, "50foo"),
)
setCampaign(campaignIDInvalidClaimableAirdrop,
tc.Shares(t, "50foo"),
tc.Shares(t, "101foo"),
)

for _, tc := range []struct {
desc string
request *types.QuerySpecialAllocationsBalanceRequest
response *types.QuerySpecialAllocationsBalanceResponse
errStatusCode codes.Code
}{
{
desc: "should fetch the balance of special allocations",
request: &types.QuerySpecialAllocationsBalanceRequest{CampaignID: campaignID},
response: &types.QuerySpecialAllocationsBalanceResponse{
GenesisDistribution: tc.Coins(t, "500foo,200bar"),
ClaimableAirdrop: tc.Coins(t, "500foo,1000baz"),
},
},
{
desc: "should fail if campaign not found",
request: &types.QuerySpecialAllocationsBalanceRequest{CampaignID: 10000},
errStatusCode: codes.NotFound,
},
{
desc: "should fail if genesis distribution is invalid",
request: &types.QuerySpecialAllocationsBalanceRequest{CampaignID: campaignIDInvalidGenesisDistribution},
errStatusCode: codes.Internal,
},
{
desc: "should fail if claimable airdrop is invalid",
request: &types.QuerySpecialAllocationsBalanceRequest{CampaignID: campaignIDInvalidClaimableAirdrop},
errStatusCode: codes.Internal,
},
} {
t.Run(tc.desc, func(t *testing.T) {
response, err := tk.CampaignKeeper.SpecialAllocationsBalance(wctx, tc.request)
if tc.errStatusCode != codes.OK {
require.EqualValues(t, tc.errStatusCode, status.Code(err))
} else {
require.NoError(t, err)
require.Equal(t, tc.response, response)
}
})
}
}
Loading

0 comments on commit 26cec92

Please sign in to comment.