mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
[R4R] This is the implementation of the total circulating supply (#376)
* adding empty query files where we will implement the cli and rest interfaces * adding querier file * adding aliases, querier, expected keepers, types, module updates * starting to work on query * adding alias for QueryCirculatingSupply * adding TotalCirculatingSupply type * adding alias for TotalCirculatingSupply type * adding QueryCirculatingSupplyCmd to clieng query file * adding register routes function * adding rest query handling function, register endpoint * fix types include statement * remove unused mux include * another import fix * remove unused variable * adding rest to module * fix missing variable names * another missing variable fix * remove dead code comment * fix typo in circulating-supply * fix import * fix querierroute return to return the module name instead of empty string * rename function, fix build issue * return error instead of nil if there is an error * import types from cosmos sdk, fix return type * set querier route to module name in key.go * adding query and rest updates * aliasing new querying circulating supply function * directly write output * fix routes * adding total supply functionality * converting from microkava to kava * Update x/validator-vesting/client/cli/query.go typo fix Co-Authored-By: Kevin Davis <karzak@users.noreply.github.com> Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
This commit is contained in:
parent
6e8e3f5bb9
commit
51fc70b5ac
@ -1,8 +1,8 @@
|
||||
// nolint
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/types/
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/keeper/
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/keeper
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/types
|
||||
package validatorvesting
|
||||
|
||||
import (
|
||||
@ -13,33 +13,35 @@ import (
|
||||
const (
|
||||
ModuleName = types.ModuleName
|
||||
StoreKey = types.StoreKey
|
||||
QuerierRoute = types.QuerierRoute
|
||||
QueryCirculatingSupply = types.QueryCirculatingSupply
|
||||
QueryTotalSupply = types.QueryTotalSupply
|
||||
)
|
||||
|
||||
var (
|
||||
// functions aliases
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
ValidatorVestingAccountKey = types.ValidatorVestingAccountKey
|
||||
CreateTestAddrs = types.CreateTestAddrs
|
||||
TestAddr = types.TestAddr
|
||||
CreateTestPubKeys = types.CreateTestPubKeys
|
||||
NewPubKey = types.NewPubKey
|
||||
NewValidatorVestingAccountRaw = types.NewValidatorVestingAccountRaw
|
||||
NewValidatorVestingAccount = types.NewValidatorVestingAccount
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
MakeTestCodec = keeper.MakeTestCodec
|
||||
CreateTestInput = keeper.CreateTestInput
|
||||
ValidatorVestingTestAccount = keeper.ValidatorVestingTestAccount
|
||||
ValidatorVestingTestAccounts = keeper.ValidatorVestingTestAccounts
|
||||
ValidatorVestingDelegatorTestAccount = keeper.ValidatorVestingDelegatorTestAccount
|
||||
CreateValidators = keeper.CreateValidators
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
ValidatorVestingAccountKey = types.ValidatorVestingAccountKey
|
||||
NewBaseQueryParams = types.NewBaseQueryParams
|
||||
CreateTestAddrs = types.CreateTestAddrs
|
||||
TestAddr = types.TestAddr
|
||||
CreateTestPubKeys = types.CreateTestPubKeys
|
||||
NewPubKey = types.NewPubKey
|
||||
NewValidatorVestingAccountRaw = types.NewValidatorVestingAccountRaw
|
||||
NewValidatorVestingAccount = types.NewValidatorVestingAccount
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
BlocktimeKey = types.BlocktimeKey
|
||||
ValidatorVestingAccountPrefix = types.ValidatorVestingAccountPrefix
|
||||
ValOpPk1 = keeper.ValOpPk1
|
||||
ValOpPk2 = keeper.ValOpPk2
|
||||
ValOpPk3 = keeper.ValOpPk3
|
||||
@ -53,12 +55,17 @@ var (
|
||||
ValConsAddr2 = keeper.ValConsAddr2
|
||||
ValConsAddr3 = keeper.ValConsAddr3
|
||||
TestAddrs = keeper.TestAddrs
|
||||
ModuleCdc = types.ModuleCdc
|
||||
BlocktimeKey = types.BlocktimeKey
|
||||
ValidatorVestingAccountPrefix = types.ValidatorVestingAccountPrefix
|
||||
)
|
||||
|
||||
type (
|
||||
Keeper = keeper.Keeper
|
||||
GenesisState = types.GenesisState
|
||||
BaseQueryParams = types.BaseQueryParams
|
||||
VestingProgress = types.VestingProgress
|
||||
CurrentPeriodProgress = types.CurrentPeriodProgress
|
||||
ValidatorVestingAccount = types.ValidatorVestingAccount
|
||||
Keeper = keeper.Keeper
|
||||
TotalCirculatingSupply = types.TotalCirculatingSupply
|
||||
)
|
||||
|
72
x/validator-vesting/client/cli/query.go
Normal file
72
x/validator-vesting/client/cli/query.go
Normal file
@ -0,0 +1,72 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
// Group nameservice queries under a subcommand
|
||||
queryValidatorVestingCmd := &cobra.Command{
|
||||
Use: "validator-vesting",
|
||||
Short: "Querying commands for the validator vesting module",
|
||||
}
|
||||
|
||||
queryValidatorVestingCmd.AddCommand(client.GetCommands(
|
||||
QueryCirculatingSupplyCmd(queryRoute, cdc),
|
||||
QueryTotalSupplyCmd(queryRoute, cdc),
|
||||
)...)
|
||||
return queryValidatorVestingCmd
|
||||
}
|
||||
|
||||
// QueryCirculatingSupplyCmd queries the total circulating supply
|
||||
func QueryCirculatingSupplyCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "circulating-supply",
|
||||
Short: "Query circulating supply information",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryCirculatingSupply), nil)
|
||||
if err != nil {
|
||||
fmt.Printf("could not get total circulating supply\n")
|
||||
return err
|
||||
}
|
||||
|
||||
var out sdk.Dec
|
||||
cdc.MustUnmarshalJSON(res, &out)
|
||||
return cliCtx.PrintOutput(out)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// QueryTotalSupplyCmd queries the total supply of ukava
|
||||
func QueryTotalSupplyCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "total-supply",
|
||||
Short: "Query total supply information",
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryTotalSupply), nil)
|
||||
if err != nil {
|
||||
fmt.Printf("could not get total supply\n")
|
||||
return err
|
||||
}
|
||||
|
||||
var out sdk.Dec
|
||||
cdc.MustUnmarshalJSON(res, &out)
|
||||
return cliCtx.PrintOutput(out)
|
||||
},
|
||||
}
|
||||
}
|
88
x/validator-vesting/client/rest/query.go
Normal file
88
x/validator-vesting/client/rest/query.go
Normal file
@ -0,0 +1,88 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
)
|
||||
|
||||
// define routes that get registered by the main application
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
|
||||
r.HandleFunc("/vesting/circulatingsupply", getCirculatingSupplyHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc("/vesting/totalsupply", getTotalSupplyHandlerFn(cliCtx)).Methods("GET")
|
||||
|
||||
}
|
||||
|
||||
func getTotalSupplyHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
params := types.NewBaseQueryParams(page, limit)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryTotalSupply)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
// directly write output instead of putting in json
|
||||
w.Write(res)
|
||||
// rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
||||
func getCirculatingSupplyHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
params := types.NewBaseQueryParams(page, limit)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryCirculatingSupply)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
// directly write output instead of putting in json
|
||||
w.Write(res)
|
||||
// rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
}
|
13
x/validator-vesting/client/rest/rest.go
Normal file
13
x/validator-vesting/client/rest/rest.go
Normal file
@ -0,0 +1,13 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
registerQueryRoutes(cliCtx, r)
|
||||
|
||||
}
|
74
x/validator-vesting/internal/keeper/querier.go
Normal file
74
x/validator-vesting/internal/keeper/querier.go
Normal file
@ -0,0 +1,74 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
|
||||
// NewQuerier returns a new querier function
|
||||
func NewQuerier(keeper Keeper) sdk.Querier {
|
||||
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
||||
switch path[0] {
|
||||
case types.QueryCirculatingSupply:
|
||||
return queryGetCirculatingSupply(ctx, req, keeper)
|
||||
case types.QueryTotalSupply:
|
||||
return queryGetTotalSupply(ctx, req, keeper)
|
||||
default:
|
||||
return nil, sdk.ErrUnknownRequest("unknown cdp query endpoint")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func queryGetTotalSupply(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
|
||||
totalSupply := keeper.supplyKeeper.GetSupply(ctx).GetTotal().AmountOf("ukava")
|
||||
supplyDec := sdk.NewDecFromInt(totalSupply).Mul(sdk.MustNewDecFromStr("0.000001"))
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, supplyDec)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetCirculatingSupply(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
|
||||
circulatingSupply := sdk.ZeroInt()
|
||||
keeper.ak.IterateAccounts(ctx,
|
||||
func(acc authexported.Account) (stop bool) {
|
||||
// exclude module account
|
||||
_, ok := acc.(supplyexported.ModuleAccountI)
|
||||
if ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// periodic vesting account
|
||||
vacc, ok := acc.(vesting.PeriodicVestingAccount)
|
||||
if ok {
|
||||
balance := vacc.GetCoins().AmountOf("ukava")
|
||||
if balance.IsZero() {
|
||||
return false
|
||||
}
|
||||
spendableBalance := vacc.SpendableCoins(ctx.BlockTime()).AmountOf("ukava")
|
||||
circulatingSupply = circulatingSupply.Add(sdk.MinInt(balance, spendableBalance))
|
||||
return false
|
||||
}
|
||||
|
||||
// base account
|
||||
bacc, ok := acc.(*auth.BaseAccount)
|
||||
if ok {
|
||||
// add all coins
|
||||
circulatingSupply = circulatingSupply.Add(bacc.GetCoins().AmountOf("ukava"))
|
||||
}
|
||||
return false
|
||||
})
|
||||
supplyDec := sdk.NewDecFromInt(circulatingSupply).Mul(sdk.MustNewDecFromStr("0.000001"))
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, supplyDec)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
@ -14,6 +14,7 @@ type AccountKeeper interface {
|
||||
GetAccount(sdk.Context, sdk.AccAddress) authexported.Account
|
||||
SetAccount(sdk.Context, authexported.Account)
|
||||
GetAllAccounts(ctx sdk.Context) (accounts []authexported.Account)
|
||||
IterateAccounts(ctx sdk.Context, cb func(account authexported.Account) (stop bool))
|
||||
}
|
||||
|
||||
// BankKeeper defines the expected bank keeper (noalias)
|
||||
@ -35,4 +36,5 @@ type SupplyKeeper interface {
|
||||
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) sdk.Error
|
||||
BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) sdk.Error
|
||||
SetModuleAccount(sdk.Context, supplyexported.ModuleAccountI)
|
||||
GetSupply(ctx sdk.Context) (supply supplyexported.SupplyI)
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ const (
|
||||
|
||||
// StoreKey to be used when creating the KVStore
|
||||
StoreKey = ModuleName
|
||||
|
||||
// QuerierRoute should be set to module name
|
||||
QuerierRoute = ModuleName
|
||||
)
|
||||
|
||||
var (
|
||||
|
17
x/validator-vesting/internal/types/querier.go
Normal file
17
x/validator-vesting/internal/types/querier.go
Normal file
@ -0,0 +1,17 @@
|
||||
package types
|
||||
|
||||
// Querier routes for the validator vesting module
|
||||
const (
|
||||
QueryCirculatingSupply = "circulating-supply"
|
||||
QueryTotalSupply = "total-supply"
|
||||
)
|
||||
|
||||
// QueryCirculatingSupplyParams defines the parameters necessary for querying for all Evidence.
|
||||
type BaseQueryParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
}
|
||||
|
||||
func NewBaseQueryParams(page, limit int) BaseQueryParams {
|
||||
return BaseQueryParams{Page: page, Limit: limit}
|
||||
}
|
@ -68,6 +68,11 @@ type ValidatorVestingAccount struct {
|
||||
DebtAfterFailedVesting sdk.Coins `json:"debt_after_failed_vesting" yaml:"debt_after_failed_vesting"`
|
||||
}
|
||||
|
||||
// TotalCirculatingSupply represents the total circulating supply of Kava
|
||||
type TotalCirculatingSupply struct {
|
||||
TotalSupply uint64 `json:"total_supply" yaml:"total_supply"` // total circulating supply
|
||||
}
|
||||
|
||||
// NewValidatorVestingAccountRaw creates a new ValidatorVestingAccount object from BaseVestingAccount
|
||||
func NewValidatorVestingAccountRaw(bva *vestingtypes.BaseVestingAccount,
|
||||
startTime int64, periods vestingtypes.Periods, validatorAddress sdk.ConsAddress, returnAddress sdk.AccAddress, signingThreshold int64) *ValidatorVestingAccount {
|
||||
|
@ -13,6 +13,8 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/client/cli"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/client/rest"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/simulation"
|
||||
)
|
||||
@ -52,13 +54,17 @@ func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
||||
}
|
||||
|
||||
// RegisterRESTRoutes registers no REST routes for the crisis module.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(_ context.CLIContext, _ *mux.Router) {}
|
||||
func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
|
||||
rest.RegisterRoutes(ctx, rtr)
|
||||
}
|
||||
|
||||
// GetTxCmd returns no root tx command for the validator-vesting module.
|
||||
func (AppModuleBasic) GetTxCmd(_ *codec.Codec) *cobra.Command { return nil }
|
||||
|
||||
// GetQueryCmd returns no root query command for the validator-vesting module.
|
||||
func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
|
||||
func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
||||
return cli.GetQueryCmd(StoreKey, cdc)
|
||||
}
|
||||
|
||||
// AppModuleSimulation defines the module simulation functions used by the auth module.
|
||||
type AppModuleSimulation struct{}
|
||||
@ -112,12 +118,12 @@ func (AppModule) NewHandler() sdk.Handler { return nil }
|
||||
|
||||
// QuerierRoute returns the auth module's querier route name.
|
||||
func (AppModule) QuerierRoute() string {
|
||||
return ""
|
||||
return ModuleName
|
||||
}
|
||||
|
||||
// NewQuerierHandler returns the auth module sdk.Querier.
|
||||
func (am AppModule) NewQuerierHandler() sdk.Querier {
|
||||
return nil
|
||||
return NewQuerier(am.keeper)
|
||||
}
|
||||
|
||||
// InitGenesis performs genesis initialization for the auth module. It returns
|
||||
|
Loading…
Reference in New Issue
Block a user