add x/mint QueryServer for backwards compatibility (#1420)

This commit is contained in:
Robert Pirtle 2022-12-09 14:39:19 -08:00 committed by GitHub
parent 016eecfcc0
commit 0ad5a5932d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 1 deletions

View File

@ -3,7 +3,12 @@ package keeper
import ( import (
"context" "context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/kava-labs/kava/x/kavamint/types" "github.com/kava-labs/kava/x/kavamint/types"
) )
@ -24,3 +29,57 @@ func (k Keeper) Inflation(c context.Context, _ *types.QueryInflationRequest) (*t
return &types.QueryInflationResponse{Inflation: inflation}, nil return &types.QueryInflationResponse{Inflation: inflation}, nil
} }
// MintQueryServer implements cosmos sdk's x/mint querier.
// x/mint was removed from kava, but the standard inflation endpoint is still registered
// for easier third party integration and backwards compatibility.
type MintQueryServer struct {
keeper Keeper
}
// NewMintQueryServer returns a service that implements x/mint's QueryServer
func NewMintQueryServer(kavamintKeeper Keeper) MintQueryServer {
return MintQueryServer{kavamintKeeper}
}
var _ minttypes.QueryServer = MintQueryServer{}
// Params is not implemented. There is no mint module.
func (MintQueryServer) Params(
_ context.Context, _ *minttypes.QueryParamsRequest,
) (*minttypes.QueryParamsResponse, error) {
return nil, status.Error(codes.Unimplemented, "x/mint has been replaced by x/kavamint")
}
// Inflation returns an adjusted inflation rate.
// The `/cosmos/mint/v1beta1/inflation` endpoint is used by third parties to calculate staking APY.
// The usual staking APY calculation takes the inflation and determines the portion of it devoted
// to staking rewards after adjusting for the bonded ratio and x/distribution community_tax.
// staking_apy = (inflation - community_tax) * total_supply / total_bonded
// Staking APY is not set directly via the x/kavamint staking_rewards_apy param.
// This endpoint returns the inflation that makes the above calculation equal to the param:
// inflation = staking_apy * total_bonded / total_supply
// NOTE: assumes x/distribution community_tax = 0
func (mq MintQueryServer) Inflation(
c context.Context, _ *minttypes.QueryInflationRequest,
) (*minttypes.QueryInflationResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
stakingApy := mq.keeper.GetParams(ctx).StakingRewardsApy
totalBonded := mq.keeper.TotalBondedTokens(ctx)
totalSupply := mq.keeper.TotalSupply(ctx)
// inflation = staking_apy * total_bonded / total_supply
inflation := stakingApy.MulInt(totalBonded).QuoInt(totalSupply)
return &minttypes.QueryInflationResponse{
Inflation: inflation,
}, nil
}
// AnnualProvisions is not implemented.
func (MintQueryServer) AnnualProvisions(
_ context.Context, _ *minttypes.QueryAnnualProvisionsRequest,
) (*minttypes.QueryAnnualProvisionsResponse, error) {
return nil, status.Error(codes.Unimplemented, "x/mint has been replaced by x/kavamint")
}

View File

@ -5,11 +5,15 @@ import (
"testing" "testing"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking"
"github.com/kava-labs/kava/x/kavamint/keeper"
"github.com/kava-labs/kava/x/kavamint/testutil" "github.com/kava-labs/kava/x/kavamint/testutil"
"github.com/kava-labs/kava/x/kavamint/types" "github.com/kava-labs/kava/x/kavamint/types"
) )
@ -18,6 +22,7 @@ type grpcQueryTestSuite struct {
testutil.KavamintTestSuite testutil.KavamintTestSuite
queryClient types.QueryClient queryClient types.QueryClient
mintQueryClient minttypes.QueryClient
} }
func (suite *grpcQueryTestSuite) SetupTest() { func (suite *grpcQueryTestSuite) SetupTest() {
@ -26,6 +31,10 @@ func (suite *grpcQueryTestSuite) SetupTest() {
queryHelper := baseapp.NewQueryServerTestHelper(suite.Ctx, suite.App.InterfaceRegistry()) queryHelper := baseapp.NewQueryServerTestHelper(suite.Ctx, suite.App.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.Keeper) types.RegisterQueryServer(queryHelper, suite.Keeper)
suite.queryClient = types.NewQueryClient(queryHelper) suite.queryClient = types.NewQueryClient(queryHelper)
mintQueryServer := keeper.NewMintQueryServer(suite.Keeper)
minttypes.RegisterQueryServer(queryHelper, mintQueryServer)
suite.mintQueryClient = minttypes.NewQueryClient(queryHelper)
} }
func TestGRPCQueryTestSuite(t *testing.T) { func TestGRPCQueryTestSuite(t *testing.T) {
@ -116,6 +125,35 @@ func (suite *grpcQueryTestSuite) TestGRPCInflationQuery() {
suite.Require().NoError(err) suite.Require().NoError(err)
suite.Require().Equal(inflation.Inflation, kavamintKeeper.CumulativeInflation(ctx)) suite.Require().Equal(inflation.Inflation, kavamintKeeper.CumulativeInflation(ctx))
suite.Require().Equal(inflation.Inflation, tc.expectedInflation) suite.Require().Equal(inflation.Inflation, tc.expectedInflation)
// ensure overridden x/mint query for inflation returns the adjusted inflation
// the adjusted inflation is the inflation that returns the correct staking apy for the
// standard staking apy calculation used by third parties:
// staking_apy = (inflation - community_tax) * total_supply / total_bonded
// => inflation = staking_apy * total_bonded / total_supply
expectedAdjustedInflation := tc.stakingApy.Mul(tc.bondedRatio)
mintQ, err := suite.mintQueryClient.Inflation(
context.Background(),
&minttypes.QueryInflationRequest{},
)
suite.NoError(err)
suite.Equal(expectedAdjustedInflation, mintQ.Inflation)
}) })
} }
} }
func (suite *grpcQueryTestSuite) TestUnimplementedMintQueries() {
suite.SetupTest()
suite.Run("Params is unimplemented", func() {
_, err := suite.mintQueryClient.Params(context.Background(), nil)
suite.Error(err)
suite.Equal(codes.Unimplemented, status.Code(err))
})
suite.Run("AnnualProvisions is unimplemented", func() {
_, err := suite.mintQueryClient.AnnualProvisions(context.Background(), nil)
suite.Error(err)
suite.Equal(codes.Unimplemented, status.Code(err))
})
}

View File

@ -15,6 +15,8 @@ import (
cdctypes "github.com/cosmos/cosmos-sdk/codec/types" cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/types/module"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/kava-labs/kava/x/kavamint/client/cli" "github.com/kava-labs/kava/x/kavamint/client/cli"
"github.com/kava-labs/kava/x/kavamint/keeper" "github.com/kava-labs/kava/x/kavamint/keeper"
"github.com/kava-labs/kava/x/kavamint/types" "github.com/kava-labs/kava/x/kavamint/types"
@ -66,6 +68,8 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
// add x/mint query handler for better 3rd party compatibility
minttypes.RegisterQueryHandlerClient(context.Background(), mux, minttypes.NewQueryClient(clientCtx))
} }
// GetTxCmd returns no root tx command for the kavamint module. // GetTxCmd returns no root tx command for the kavamint module.
@ -118,6 +122,11 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// module-specific gRPC queries. // module-specific gRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper) types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
// register x/mint query server.
// x/mint was replaced by this module but we still want 3rd parties to be able to
// request the original sdk endpoints.
minttypes.RegisterQueryServer(cfg.QueryServer(), keeper.NewMintQueryServer(am.keeper))
} }
// InitGenesis performs genesis initialization for the kavamint module. It returns // InitGenesis performs genesis initialization for the kavamint module. It returns