diff --git a/.gitignore b/.gitignore index c305c13..8052735 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,7 @@ coverage.txt tools-stamp __debug_bin profile.out +tmp/ +run.sh testing/e2e/networks/*/ square/testdata diff --git a/app/app.go b/app/app.go index 02782ba..4d414d4 100644 --- a/app/app.go +++ b/app/app.go @@ -5,6 +5,9 @@ import ( "os" "path/filepath" + "github.com/celestiaorg/celestia-app/x/mint" + mintkeeper "github.com/celestiaorg/celestia-app/x/mint/keeper" + minttypes "github.com/celestiaorg/celestia-app/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -53,9 +56,6 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta2 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" oldgovtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/cosmos-sdk/x/mint" - mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -308,8 +308,12 @@ func New( appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), ) app.MintKeeper = mintkeeper.NewKeeper( - appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), &stakingKeeper, - app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, + appCodec, + keys[minttypes.StoreKey], + &stakingKeeper, + app.AccountKeeper, + app.BankKeeper, + authtypes.FeeCollectorName, ) app.DistrKeeper = distrkeeper.NewKeeper( appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper, @@ -421,7 +425,7 @@ func New( feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), diff --git a/app/default_overrides.go b/app/default_overrides.go index 655392b..f06204a 100644 --- a/app/default_overrides.go +++ b/app/default_overrides.go @@ -4,6 +4,8 @@ import ( "encoding/json" "github.com/celestiaorg/celestia-app/pkg/appconsts" + "github.com/celestiaorg/celestia-app/x/mint" + minttypes "github.com/celestiaorg/celestia-app/x/mint/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank" @@ -14,8 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - "github.com/cosmos/cosmos-sdk/x/mint" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" "github.com/cosmos/cosmos-sdk/x/staking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -95,7 +95,7 @@ type mintModule struct { // DefaultGenesis returns custom x/mint module genesis state. func (mintModule) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { genState := minttypes.DefaultGenesisState() - genState.Params.MintDenom = BondDenom + genState.Minter.BondDenom = BondDenom return cdc.MustMarshalJSON(genState) } diff --git a/app/test/std_sdk_test.go b/app/test/std_sdk_test.go index f6e277a..e4dd42d 100644 --- a/app/test/std_sdk_test.go +++ b/app/test/std_sdk_test.go @@ -162,7 +162,12 @@ func (s *StandardSDKIntegrationTestSuite) TestStandardSDK() { name: "create legacy community spend governance proposal", msgFunc: func() (msgs []sdk.Msg, signer string) { account := s.unusedAccount() - coins := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000))) + // Note: this test depends on at least one coin being present + // in the community pool. Funds land in the community pool due + // to inflation so if 1 coin is not present in the community + // pool, consider expanding the block interval or waiting for + // more blocks to be produced prior to executing this test case. + coins := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(1))) content := disttypes.NewCommunityPoolSpendProposal( "title", "description", diff --git a/go.mod b/go.mod index 998d00e..ddd0d23 100644 --- a/go.mod +++ b/go.mod @@ -191,7 +191,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.102.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/proto/celestia/mint/v1/genesis.proto b/proto/celestia/mint/v1/genesis.proto new file mode 100644 index 0000000..f4da8cf --- /dev/null +++ b/proto/celestia/mint/v1/genesis.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package celestia.mint.v1; + +import "gogoproto/gogo.proto"; +import "celestia/mint/v1/mint.proto"; + +option go_package = "github.com/celestiaorg/celestia-app/x/mint/types"; + +// GenesisState defines the mint module's genesis state. +message GenesisState { + // minter is a space for holding current inflation information. + Minter minter = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/celestia/mint/v1/mint.proto b/proto/celestia/mint/v1/mint.proto new file mode 100644 index 0000000..47f74a9 --- /dev/null +++ b/proto/celestia/mint/v1/mint.proto @@ -0,0 +1,36 @@ +syntax = "proto3"; +package celestia.mint.v1; + +option go_package = "github.com/celestiaorg/celestia-app/x/mint/types"; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; + +// Minter represents the mint state. +message Minter { + // InflationRate is the rate at which new tokens should be minted for the + // current year. For example if InflationRate=0.1, then 10% of the total + // supply will be minted over the course of the year. + string inflation_rate = 1 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // AnnualProvisions is the total number of tokens to be minted in the current + // year due to inflation. + string annual_provisions = 2 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // GenesisTime is the timestamp of the genesis block. + google.protobuf.Timestamp genesis_time = 3 [(gogoproto.stdtime) = true]; + + // PreviousBlockTime is the timestamp of the previous block. + google.protobuf.Timestamp previous_block_time = 4 [(gogoproto.stdtime) = true]; + + // BondDenom is the denomination of the token that should be minted. + string bond_denom = 5; +} diff --git a/proto/celestia/mint/v1/query.proto b/proto/celestia/mint/v1/query.proto new file mode 100644 index 0000000..5df7fe8 --- /dev/null +++ b/proto/celestia/mint/v1/query.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; +package celestia.mint.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "celestia/mint/v1/mint.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/celestiaorg/celestia-app/x/mint/types"; + +// Query defines the gRPC querier service. +service Query { + // InflationRate returns the current inflation rate. + rpc InflationRate(QueryInflationRateRequest) returns (QueryInflationRateResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/inflation_rate"; + } + + // AnnualProvisions returns the current annual provisions. + rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions"; + } + + // GenesisTime returns the genesis time. + rpc GenesisTime(QueryGenesisTimeRequest) returns (QueryGenesisTimeResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/genesis_time"; + } +} + +// QueryInflationRateRequest is the request type for the Query/InflationRate RPC method. +message QueryInflationRateRequest {} + +// QueryInflationRateResponse is the response type for the Query/InflationRate RPC +// method. +message QueryInflationRateResponse { + // InflationRate is the current inflation rate. + bytes inflation_rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// QueryAnnualProvisionsRequest is the request type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsRequest {} + +// QueryAnnualProvisionsResponse is the response type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsResponse { + // AnnualProvisions is the current annual provisions. + bytes annual_provisions = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// QueryGenesisTimeRequest is the request type for the Query/GenesisTime RPC method. +message QueryGenesisTimeRequest {} + +// QueryGenesisTimeResponse is the response type for the Query/GenesisTime RPC method. +message QueryGenesisTimeResponse { + // GenesisTime is the timestamp associated with the first block. + google.protobuf.Timestamp genesis_time = 1 [(gogoproto.stdtime) = true]; +} diff --git a/x/mint/README.md b/x/mint/README.md new file mode 100644 index 0000000..2d189d3 --- /dev/null +++ b/x/mint/README.md @@ -0,0 +1,52 @@ +# `x/mint` + +`x/mint` is a fork of the Cosmos SDK `x/mint` module that makes some changes to the inflation mechanism. + +1. Remove all parameters from the module +1. Calculate inflation rate once per year based on the number of years since genesis +1. Calculate annual provisions once per year based on the total supply +1. Calculate block provision once per block based on the number of seconds elapsed between the current block and the previous block + +## Constants + +See [./types/constants.go](./types/constants.go) for the constants used in this module. + +Note: this module assumes `DaysPerYear = 365.2425` so when modifying tests, developers must define durations based on this assumption because ordinary durations won't return the expected results. In other words: + +```go +// oneYear is 31,556,952 seconds which will likely return expected results in tests +oneYear, err := time.ParseDuration(fmt.Sprintf("%vs", minttypes.SecondsPerYear)) + +// this oneYear is 31,536,000 seconds which will likely return unexpected results in tests +oneYear := time.Hour * 24 * 365 +``` + +## Inflation Schedule + +| Year | Inflation (%) | +|------|-------------------| +| 0 | 8.00 | +| 1 | 7.20 | +| 2 | 6.48 | +| 3 | 5.832 | +| 4 | 5.2488 | +| 5 | 4.72392 | +| 6 | 4.251528 | +| 7 | 3.8263752 | +| 8 | 3.44373768 | +| 9 | 3.099363912 | +| 10 | 2.7894275208 | +| 11 | 2.51048476872 | +| 12 | 2.259436291848 | +| 13 | 2.0334926626632 | +| 14 | 1.83014339639688 | +| 15 | 1.647129056757192 | +| 16 | 1.50 | +| 17 | 1.50 | +| 18 | 1.50 | +| 19 | 1.50 | +| 20 | 1.50 | + +## References + +1. ADR-019 diff --git a/x/mint/abci.go b/x/mint/abci.go new file mode 100644 index 0000000..d75834b --- /dev/null +++ b/x/mint/abci.go @@ -0,0 +1,93 @@ +package mint + +import ( + "time" + + "github.com/celestiaorg/celestia-app/x/mint/keeper" + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// BeginBlocker updates the inflation rate, annual provisions, and then mints +// the block provision for the current block. +func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + maybeSetGenesisTime(ctx, k) + maybeUpdateMinter(ctx, k) + mintBlockProvision(ctx, k) + setPreviousBlockTime(ctx, k) +} + +// maybeSetGenesisTime sets the genesis time if the current block height is 1. +func maybeSetGenesisTime(ctx sdk.Context, k keeper.Keeper) { + if ctx.BlockHeight() == 1 { + genesisTime := ctx.BlockTime() + minter := k.GetMinter(ctx) + minter.GenesisTime = &genesisTime + k.SetMinter(ctx, minter) + } +} + +// maybeUpdateMinter updates the inflation rate and annual provisions if the +// inflation rate has changed. +func maybeUpdateMinter(ctx sdk.Context, k keeper.Keeper) { + minter := k.GetMinter(ctx) + newInflationRate := minter.CalculateInflationRate(ctx) + if newInflationRate == minter.InflationRate { + // The minter's InflationRate AnnualProvisions already reflect the + // values for this year. Exit early because we don't need to update + // them. + return + } + minter.InflationRate = newInflationRate + k.SetMinter(ctx, minter) + + totalSupply := k.StakingTokenSupply(ctx) + minter.AnnualProvisions = minter.CalculateAnnualProvisions(totalSupply) + k.SetMinter(ctx, minter) +} + +// mintBlockProvision mints the block provision for the current block. +func mintBlockProvision(ctx sdk.Context, k keeper.Keeper) { + minter := k.GetMinter(ctx) + if minter.PreviousBlockTime == nil { + // exit early if previous block time is nil + // this is expected to happen for block height = 1 + return + } + + toMintCoin := minter.CalculateBlockProvision(ctx.BlockTime(), *minter.PreviousBlockTime) + toMintCoins := sdk.NewCoins(toMintCoin) + + err := k.MintCoins(ctx, toMintCoins) + if err != nil { + panic(err) + } + + err = k.SendCoinsToFeeCollector(ctx, toMintCoins) + if err != nil { + panic(err) + } + + if toMintCoin.Amount.IsInt64() { + defer telemetry.ModuleSetGauge(types.ModuleName, float32(toMintCoin.Amount.Int64()), "minted_tokens") + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeMint, + sdk.NewAttribute(types.AttributeKeyInflationRate, minter.InflationRate.String()), + sdk.NewAttribute(types.AttributeKeyAnnualProvisions, minter.AnnualProvisions.String()), + sdk.NewAttribute(sdk.AttributeKeyAmount, toMintCoin.Amount.String()), + ), + ) +} + +func setPreviousBlockTime(ctx sdk.Context, k keeper.Keeper) { + minter := k.GetMinter(ctx) + blockTime := ctx.BlockTime() + minter.PreviousBlockTime = &blockTime + k.SetMinter(ctx, minter) +} diff --git a/x/mint/abci_test.go b/x/mint/abci_test.go new file mode 100644 index 0000000..d83b39f --- /dev/null +++ b/x/mint/abci_test.go @@ -0,0 +1,169 @@ +package mint_test + +import ( + "fmt" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/test/util" + "github.com/celestiaorg/celestia-app/x/mint" + minttypes "github.com/celestiaorg/celestia-app/x/mint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + tmlog "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestGenesisTime(t *testing.T) { + app, _ := util.SetupTestAppWithGenesisValSet() + ctx := sdk.NewContext(app.CommitMultiStore(), types.Header{}, false, tmlog.NewNopLogger()) + unixEpoch := time.Unix(0, 0).UTC() + fixedTime := time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC() + + type testCase struct { + name string + ctx sdk.Context + want time.Time + } + + testCases := []testCase{ + { + name: "initially genesis time is unix epoch", + ctx: ctx.WithBlockHeight(0).WithBlockTime(unixEpoch), + want: unixEpoch, + }, + { + name: "genesis time is set to time of first block", + ctx: ctx.WithBlockHeight(1).WithBlockTime(fixedTime), + want: fixedTime, + }, + { + name: "genesis time remains set to time of first block", + ctx: ctx.WithBlockHeight(2).WithBlockTime(fixedTime.Add(time.Hour)), + want: fixedTime, + }, + } + + for _, tc := range testCases { + mint.BeginBlocker(tc.ctx, app.MintKeeper) + got, err := app.MintKeeper.GenesisTime(ctx, &minttypes.QueryGenesisTimeRequest{}) + assert.NoError(t, err) + assert.Equal(t, &tc.want, got.GenesisTime) + } +} + +func TestInflationRate(t *testing.T) { + app, _ := util.SetupTestAppWithGenesisValSet() + ctx := sdk.NewContext(app.CommitMultiStore(), types.Header{}, false, tmlog.NewNopLogger()) + unixEpoch := time.Unix(0, 0).UTC() + yearZero := time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC() + oneYear, err := time.ParseDuration(fmt.Sprintf("%vns", minttypes.NanosecondsPerYear)) + assert.NoError(t, err) + yearOne := yearZero.Add(oneYear) + yearTwo := yearZero.Add(2 * oneYear) + yearTwenty := yearZero.Add(20 * oneYear) + + type testCase struct { + name string + ctx sdk.Context + want sdk.Dec + } + + testCases := []testCase{ + { + name: "inflation rate is 0.08 initially", + ctx: ctx.WithBlockHeight(0).WithBlockTime(unixEpoch), + want: sdk.NewDecWithPrec(8, 2), // 0.08 + }, + { + name: "inflation rate is 0.08 for year zero", + ctx: ctx.WithBlockHeight(1).WithBlockTime(yearZero), + want: sdk.NewDecWithPrec(8, 2), // 0.08 + }, + { + name: "inflation rate is 0.08 for year one minus one minute", + ctx: ctx.WithBlockTime(yearOne.Add(-time.Minute)), + want: sdk.NewDecWithPrec(8, 2), // 0.08 + }, + { + name: "inflation rate is 0.072 for year one", + ctx: ctx.WithBlockTime(yearOne), + want: sdk.NewDecWithPrec(72, 3), // 0.072 + }, + { + name: "inflation rate is 0.0648 for year two", + ctx: ctx.WithBlockTime(yearTwo), + want: sdk.NewDecWithPrec(648, 4), // 0.0648 + }, + { + name: "inflation rate is 0.015 for year twenty", + ctx: ctx.WithBlockTime(yearTwenty), + want: sdk.NewDecWithPrec(15, 3), // 0.015 + }, + } + + for _, tc := range testCases { + mint.BeginBlocker(tc.ctx, app.MintKeeper) + got, err := app.MintKeeper.InflationRate(ctx, &minttypes.QueryInflationRateRequest{}) + assert.NoError(t, err) + assert.Equal(t, tc.want, got.InflationRate) + } +} + +func TestAnnualProvisions(t *testing.T) { + app, _ := util.SetupTestAppWithGenesisValSet() + ctx := sdk.NewContext(app.CommitMultiStore(), types.Header{}, false, tmlog.NewNopLogger()) + unixEpoch := time.Unix(0, 0).UTC() + yearZero := time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC() + oneYear, err := time.ParseDuration(fmt.Sprintf("%vns", minttypes.NanosecondsPerYear)) + assert.NoError(t, err) + yearOne := yearZero.Add(oneYear) + yearTwo := yearZero.Add(2 * oneYear) + yearTwenty := yearZero.Add(20 * oneYear) + + type testCase struct { + name string + ctx sdk.Context + want sdk.Dec + } + + testCases := []testCase{ + { + name: "annual provisions is 80,000 initially", + ctx: ctx.WithBlockHeight(0).WithBlockTime(unixEpoch), + want: sdk.NewDec(80_000), // 1,000,000 (total supply) * 0.08 (inflation rate) + }, + { + name: "annual provisions is 80,000 for year zero", + ctx: ctx.WithBlockHeight(1).WithBlockTime(yearZero), + want: sdk.NewDec(80_000), // 1,000,000 (total supply) * 0.08 (inflation rate) + }, + { + name: "annual provisions is 80,000 for year one minus one minute", + ctx: ctx.WithBlockTime(yearOne.Add(-time.Minute)), + want: sdk.NewDec(80_000), // 1,000,000 (total supply) * 0.08 (inflation rate) + }, + { + name: "annual provisions is 72,000 for year one", + ctx: ctx.WithBlockTime(yearOne), + want: sdk.NewDec(72_000), // 1,000,000 (total supply) * 0.072 (inflation rate) + }, + { + name: "annual provisions is 64,800 for year two", + ctx: ctx.WithBlockTime(yearTwo), + want: sdk.NewDec(64_800), // 1,000,000 (total supply) * 0.0648 (inflation rate) + }, + { + name: "annual provisions is 15,000 for year twenty", + ctx: ctx.WithBlockTime(yearTwenty), + want: sdk.NewDec(15_000), // 1,000,000 (total supply) * 0.015 (inflation rate) + }, + } + + for _, tc := range testCases { + mint.BeginBlocker(tc.ctx, app.MintKeeper) + got, err := app.MintKeeper.AnnualProvisions(ctx, &minttypes.QueryAnnualProvisionsRequest{}) + assert.NoError(t, err) + assert.Equal(t, tc.want, got.AnnualProvisions) + } +} diff --git a/x/mint/client/cli/query.go b/x/mint/client/cli/query.go new file mode 100644 index 0000000..b92636f --- /dev/null +++ b/x/mint/client/cli/query.go @@ -0,0 +1,116 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" +) + +// GetQueryCmd returns the CLI query commands for the mint module. +func GetQueryCmd() *cobra.Command { + mintQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the mint module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + mintQueryCmd.AddCommand( + GetCmdQueryInflationRate(), + GetCmdQueryAnnualProvisions(), + GetCmdQueryGenesisTime(), + ) + + return mintQueryCmd +} + +// GetCmdQueryInflationRate implements a command to return the current mint +// inflation rate. +func GetCmdQueryInflationRate() *cobra.Command { + cmd := &cobra.Command{ + Use: "inflation", + Short: "Query the current inflation rate", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + request := &types.QueryInflationRateRequest{} + res, err := queryClient.InflationRate(cmd.Context(), request) + if err != nil { + return err + } + + return clientCtx.PrintString(fmt.Sprintf("%s\n", res.InflationRate)) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryAnnualProvisions implements a command to return the current mint +// annual provisions. +func GetCmdQueryAnnualProvisions() *cobra.Command { + cmd := &cobra.Command{ + Use: "annual-provisions", + Short: "Query the current annual provisions", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + request := &types.QueryAnnualProvisionsRequest{} + res, err := queryClient.AnnualProvisions(cmd.Context(), request) + if err != nil { + return err + } + + return clientCtx.PrintString(fmt.Sprintf("%s\n", res.AnnualProvisions)) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryGenesisTime implements a command to return the genesis time. +func GetCmdQueryGenesisTime() *cobra.Command { + cmd := &cobra.Command{ + Use: "genesis-time", + Short: "Query the genesis time", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + request := &types.QueryGenesisTimeRequest{} + res, err := queryClient.GenesisTime(cmd.Context(), request) + if err != nil { + return err + } + + return clientCtx.PrintString(fmt.Sprintf("%s\n", res.GenesisTime)) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/mint/client/testutil/grpc_test.go b/x/mint/client/testutil/grpc_test.go new file mode 100644 index 0000000..a2959c2 --- /dev/null +++ b/x/mint/client/testutil/grpc_test.go @@ -0,0 +1,54 @@ +package testutil + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" + + "github.com/gogo/protobuf/proto" + + minttypes "github.com/celestiaorg/celestia-app/x/mint/types" +) + +func (s *IntegrationTestSuite) TestQueryGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + testCases := []struct { + name string + url string + headers map[string]string + respType proto.Message + expected proto.Message + }{ + { + "gRPC request inflation rate", + fmt.Sprintf("%s/cosmos/mint/v1beta1/inflation_rate", baseURL), + map[string]string{}, + &minttypes.QueryInflationRateResponse{}, + &minttypes.QueryInflationRateResponse{ + InflationRate: sdk.NewDecWithPrec(8, 2), + }, + }, + { + "gRPC request annual provisions", + fmt.Sprintf("%s/cosmos/mint/v1beta1/annual_provisions", baseURL), + map[string]string{ + grpctypes.GRPCBlockHeightHeader: "1", + }, + &minttypes.QueryAnnualProvisionsResponse{}, + &minttypes.QueryAnnualProvisionsResponse{ + AnnualProvisions: sdk.NewDec(40_000_000), + }, + }, + } + for _, tc := range testCases { + resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers) + s.Run(tc.name, func() { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + }) + } +} diff --git a/x/mint/client/testutil/suite_test.go b/x/mint/client/testutil/suite_test.go new file mode 100644 index 0000000..a1346d7 --- /dev/null +++ b/x/mint/client/testutil/suite_test.go @@ -0,0 +1,131 @@ +package testutil + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/suite" + tmcli "github.com/tendermint/tendermint/libs/cli" + + "github.com/celestiaorg/celestia-app/x/mint/client/cli" + minttypes "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/client/flags" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + + appnetwork "github.com/celestiaorg/celestia-app/test/util/network" + "github.com/cosmos/cosmos-sdk/testutil/network" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite { + return &IntegrationTestSuite{cfg: cfg} +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up x/mint integration test suite") + + genesisState := s.cfg.GenesisState + var mintData minttypes.GenesisState + s.Require().NoError(s.cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData)) + + var err error + s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) + s.Require().NoError(err) + + _, err = s.network.WaitForHeight(1) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down x/mint integration test suite") + s.network.Cleanup() +} + +func (s *IntegrationTestSuite) jsonArgs() []string { + return []string{fmt.Sprintf("--%s=1", flags.FlagHeight), fmt.Sprintf("--%s=json", tmcli.OutputFlag)} +} + +func (s *IntegrationTestSuite) textArgs() []string { + return []string{fmt.Sprintf("--%s=1", flags.FlagHeight), fmt.Sprintf("--%s=json", tmcli.OutputFlag)} +} + +func (s *IntegrationTestSuite) TestGetCmdQueryInflationRate() { + val := s.network.Validators[0] + + testCases := []struct { + name string + args []string + want string + }{ + { + name: "json output", + args: s.jsonArgs(), + want: `0.080000000000000000`, + }, + { + name: "text output", + args: s.textArgs(), + want: `0.080000000000000000`, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQueryInflationRate() + clientCtx := val.ClientCtx + + got, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + s.Require().Equal(tc.want, strings.TrimSpace(got.String())) + }) + } +} + +func (s *IntegrationTestSuite) TestGetCmdQueryAnnualProvisions() { + val := s.network.Validators[0] + + testCases := []struct { + name string + args []string + want string + }{ + { + name: "json output", + args: s.jsonArgs(), + want: `40000000.000000000000000000`, + }, + { + name: "text output", + args: s.textArgs(), + want: `40000000.000000000000000000`, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQueryAnnualProvisions() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + s.Require().NoError(err) + s.Require().Equal(tc.want, strings.TrimSpace(out.String())) + }) + } +} + +func TestIntegrationTestSuite(t *testing.T) { + cfg := appnetwork.DefaultConfig() + cfg.NumValidators = 1 + suite.Run(t, NewIntegrationTestSuite(cfg)) +} diff --git a/x/mint/keeper/genesis.go b/x/mint/keeper/genesis.go new file mode 100644 index 0000000..73aaeae --- /dev/null +++ b/x/mint/keeper/genesis.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "github.com/celestiaorg/celestia-app/x/mint/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis new mint genesis +func (keeper Keeper) InitGenesis(ctx sdk.Context, ak types.AccountKeeper, data *types.GenesisState) { + keeper.SetMinter(ctx, data.Minter) + ak.GetModuleAccount(ctx, types.ModuleName) +} + +// ExportGenesis returns a GenesisState for a given context and keeper. +func (keeper Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + minter := keeper.GetMinter(ctx) + return types.NewGenesisState(minter) +} diff --git a/x/mint/keeper/grpc_query.go b/x/mint/keeper/grpc_query.go new file mode 100644 index 0000000..d18d5e2 --- /dev/null +++ b/x/mint/keeper/grpc_query.go @@ -0,0 +1,34 @@ +package keeper + +import ( + "context" + + "github.com/celestiaorg/celestia-app/x/mint/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ types.QueryServer = Keeper{} + +// InflationRate returns minter.InflationRate of the mint module. +func (k Keeper) InflationRate(c context.Context, _ *types.QueryInflationRateRequest) (*types.QueryInflationRateResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + minter := k.GetMinter(ctx) + + return &types.QueryInflationRateResponse{InflationRate: minter.InflationRate}, nil +} + +// AnnualProvisions returns minter.AnnualProvisions of the mint module. +func (k Keeper) AnnualProvisions(c context.Context, _ *types.QueryAnnualProvisionsRequest) (*types.QueryAnnualProvisionsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + minter := k.GetMinter(ctx) + + return &types.QueryAnnualProvisionsResponse{AnnualProvisions: minter.AnnualProvisions}, nil +} + +// GenesisTime returns minter.GensisTime of the mint module. +func (k Keeper) GenesisTime(c context.Context, _ *types.QueryGenesisTimeRequest) (*types.QueryGenesisTimeResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + minter := k.GetMinter(ctx) + + return &types.QueryGenesisTimeResponse{GenesisTime: minter.GenesisTime}, nil +} diff --git a/x/mint/keeper/grpc_query_test.go b/x/mint/keeper/grpc_query_test.go new file mode 100644 index 0000000..670692d --- /dev/null +++ b/x/mint/keeper/grpc_query_test.go @@ -0,0 +1,57 @@ +package keeper_test //nolint:all + +import ( + gocontext "context" + "testing" + + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/celestiaorg/celestia-app/app" + testutil "github.com/celestiaorg/celestia-app/test/util" + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type MintTestSuite struct { + suite.Suite + + app *app.App + ctx sdk.Context + queryClient types.QueryClient +} + +func (suite *MintTestSuite) SetupTest() { + testApp, _ := testutil.SetupTestAppWithGenesisValSet() + ctx := testApp.NewContext(false, tmproto.Header{}) + + queryHelper := baseapp.NewQueryServerTestHelper(ctx, testApp.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, testApp.MintKeeper) + queryClient := types.NewQueryClient(queryHelper) + + suite.app = testApp + suite.ctx = ctx + + suite.queryClient = queryClient +} + +func (suite *MintTestSuite) TestGRPC() { + app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient + + inflation, err := queryClient.InflationRate(gocontext.Background(), &types.QueryInflationRateRequest{}) + suite.Require().NoError(err) + suite.Require().Equal(inflation.InflationRate, app.MintKeeper.GetMinter(ctx).InflationRate) + + annualProvisions, err := queryClient.AnnualProvisions(gocontext.Background(), &types.QueryAnnualProvisionsRequest{}) + suite.Require().NoError(err) + suite.Require().Equal(annualProvisions.AnnualProvisions, app.MintKeeper.GetMinter(ctx).AnnualProvisions) + + genesisTime, err := queryClient.GenesisTime(gocontext.Background(), &types.QueryGenesisTimeRequest{}) + suite.Require().NoError(err) + suite.Require().Equal(genesisTime.GenesisTime, app.MintKeeper.GetMinter(ctx).GenesisTime) +} + +func TestMintTestSuite(t *testing.T) { + suite.Run(t, new(MintTestSuite)) +} diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go new file mode 100644 index 0000000..4b01d11 --- /dev/null +++ b/x/mint/keeper/keeper.go @@ -0,0 +1,89 @@ +package keeper + +import ( + "cosmossdk.io/math" + "github.com/tendermint/tendermint/libs/log" + + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Keeper of the mint store +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + stakingKeeper types.StakingKeeper + bankKeeper types.BankKeeper + feeCollectorName string +} + +// NewKeeper creates a new mint Keeper instance. +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + stakingKeeper types.StakingKeeper, + ak types.AccountKeeper, + bankKeeper types.BankKeeper, + feeCollectorName string, +) Keeper { + // Ensure the mint module account has been set + if addr := ak.GetModuleAddress(types.ModuleName); addr == nil { + panic("the mint module account has not been set") + } + + return Keeper{ + cdc: cdc, + storeKey: storeKey, + stakingKeeper: stakingKeeper, + bankKeeper: bankKeeper, + feeCollectorName: feeCollectorName, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", "x/"+types.ModuleName) +} + +// GetMinter returns the minter. +func (k Keeper) GetMinter(ctx sdk.Context) (minter types.Minter) { + store := ctx.KVStore(k.storeKey) + b := store.Get(types.MintKey) + if b == nil { + panic("stored minter should not have been nil") + } + + k.cdc.MustUnmarshal(b, &minter) + return +} + +// SetMinter sets the minter. +func (k Keeper) SetMinter(ctx sdk.Context, minter types.Minter) { + store := ctx.KVStore(k.storeKey) + b := k.cdc.MustMarshal(&minter) + store.Set(types.MintKey, b) +} + +// StakingTokenSupply implements an alias call to the underlying staking keeper's +// StakingTokenSupply. +func (k Keeper) StakingTokenSupply(ctx sdk.Context) math.Int { + return k.stakingKeeper.StakingTokenSupply(ctx) +} + +// MintCoins implements an alias call to the underlying bank keeper's +// MintCoins. +func (k Keeper) MintCoins(ctx sdk.Context, newCoins sdk.Coins) error { + if newCoins.Empty() { + return nil + } + + return k.bankKeeper.MintCoins(ctx, types.ModuleName, newCoins) +} + +// SendCoinsToFeeCollector sends newly minted coins from the x/mint module to +// the x/auth fee collector module account. +func (k Keeper) SendCoinsToFeeCollector(ctx sdk.Context, coins sdk.Coins) error { + return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.feeCollectorName, coins) +} diff --git a/x/mint/keeper/querier.go b/x/mint/keeper/querier.go new file mode 100644 index 0000000..27e19c8 --- /dev/null +++ b/x/mint/keeper/querier.go @@ -0,0 +1,64 @@ +package keeper + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "cosmossdk.io/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// NewQuerier returns a minting Querier handler. +func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return func(ctx sdk.Context, path []string, _ abci.RequestQuery) ([]byte, error) { + switch path[0] { + case types.QueryInflationRate: + return queryInflationRate(ctx, k, legacyQuerierCdc) + + case types.QueryAnnualProvisions: + return queryAnnualProvisions(ctx, k, legacyQuerierCdc) + + case types.QueryGenesisTime: + return queryGenesisTime(ctx, k, legacyQuerierCdc) + + default: + return nil, errors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) + } + } +} + +func queryInflationRate(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { + minter := k.GetMinter(ctx) + + res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.InflationRate) + if err != nil { + return nil, errors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + +func queryAnnualProvisions(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { + minter := k.GetMinter(ctx) + + res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.AnnualProvisions) + if err != nil { + return nil, errors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + +func queryGenesisTime(ctx sdk.Context, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) { + minter := k.GetMinter(ctx) + + res, err := codec.MarshalJSONIndent(legacyQuerierCdc, minter.GenesisTime) + if err != nil { + return nil, errors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} diff --git a/x/mint/keeper/querier_test.go b/x/mint/keeper/querier_test.go new file mode 100644 index 0000000..b3ebec4 --- /dev/null +++ b/x/mint/keeper/querier_test.go @@ -0,0 +1,106 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/celestiaorg/celestia-app/app" + testutil "github.com/celestiaorg/celestia-app/test/util" + keep "github.com/celestiaorg/celestia-app/x/mint/keeper" + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type MintKeeperTestSuite struct { + suite.Suite + + app *app.App + ctx sdk.Context + legacyQuerierCdc *codec.AminoCodec +} + +func (suite *MintKeeperTestSuite) SetupTest() { + testApp, _ := testutil.SetupTestAppWithGenesisValSet() + ctx := testApp.NewContext(true, tmproto.Header{}) + + testApp.MintKeeper.SetMinter(ctx, types.DefaultMinter()) + + legacyQuerierCdc := codec.NewAminoCodec(testApp.LegacyAmino()) + + suite.app = testApp + suite.ctx = ctx + suite.legacyQuerierCdc = legacyQuerierCdc +} + +func (suite *MintKeeperTestSuite) TestNewQuerier(t *testing.T) { + app, ctx, legacyQuerierCdc := suite.app, suite.ctx, suite.legacyQuerierCdc + querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + + query := abci.RequestQuery{ + Path: "", + Data: []byte{}, + } + + _, err := querier(ctx, []string{types.QueryInflationRate}, query) + require.NoError(t, err) + + _, err = querier(ctx, []string{types.QueryAnnualProvisions}, query) + require.NoError(t, err) + + _, err = querier(ctx, []string{types.QueryGenesisTime}, query) + require.NoError(t, err) + + _, err = querier(ctx, []string{"foo"}, query) + require.Error(t, err) +} + +func (suite *MintKeeperTestSuite) TestQueryInflationRate(t *testing.T) { + app, ctx, legacyQuerierCdc := suite.app, suite.ctx, suite.legacyQuerierCdc + querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + + var inflation sdk.Dec + + res, sdkErr := querier(ctx, []string{types.QueryInflationRate}, abci.RequestQuery{}) + require.NoError(t, sdkErr) + + err := app.LegacyAmino().UnmarshalJSON(res, &inflation) + require.NoError(t, err) + + require.Equal(t, app.MintKeeper.GetMinter(ctx).InflationRate, inflation) +} + +func (suite *MintKeeperTestSuite) TestQueryAnnualProvisions(t *testing.T) { + app, ctx, legacyQuerierCdc := suite.app, suite.ctx, suite.legacyQuerierCdc + querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + + var annualProvisions sdk.Dec + + res, sdkErr := querier(ctx, []string{types.QueryAnnualProvisions}, abci.RequestQuery{}) + require.NoError(t, sdkErr) + + err := app.LegacyAmino().UnmarshalJSON(res, &annualProvisions) + require.NoError(t, err) + + require.Equal(t, app.MintKeeper.GetMinter(ctx).AnnualProvisions, annualProvisions) +} + +func (suite *MintKeeperTestSuite) TestQueryGenesisTime(t *testing.T) { + app, ctx, legacyQuerierCdc := suite.app, suite.ctx, suite.legacyQuerierCdc + querier := keep.NewQuerier(app.MintKeeper, legacyQuerierCdc.LegacyAmino) + + var genesisTime *time.Time + + res, sdkErr := querier(ctx, []string{types.QueryGenesisTime}, abci.RequestQuery{}) + require.NoError(t, sdkErr) + + err := app.LegacyAmino().UnmarshalJSON(res, &genesisTime) + require.NoError(t, err) + + require.Equal(t, app.MintKeeper.GetMinter(ctx).GenesisTime, genesisTime) +} diff --git a/x/mint/module.go b/x/mint/module.go new file mode 100644 index 0000000..c2ff8b1 --- /dev/null +++ b/x/mint/module.go @@ -0,0 +1,168 @@ +package mint + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/celestiaorg/celestia-app/x/mint/client/cli" + "github.com/celestiaorg/celestia-app/x/mint/keeper" + "github.com/celestiaorg/celestia-app/x/mint/simulation" + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the mint module. +type AppModuleBasic struct { + cdc codec.Codec +} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the mint module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the mint module's types on the given LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {} + +// RegisterInterfaces registers the module's interface types +func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} + +// DefaultGenesis returns default genesis state as raw bytes for the mint +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the mint module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return types.ValidateGenesis(data) +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the mint module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} + +// GetTxCmd returns no root tx command for the mint module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } + +// GetQueryCmd returns the root query command for the mint module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// AppModule implements an application module for the mint module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper + authKeeper types.AccountKeeper +} + +// NewAppModule creates a new AppModule object. If the InflationCalculationFn +// argument is nil, then the SDK's default inflation function will be used. +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + authKeeper: ak, + } +} + +// Name returns the mint module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants registers the mint module invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Deprecated: Route returns the message routing key for the mint module. +func (AppModule) Route() sdk.Route { return sdk.Route{} } + +// QuerierRoute returns the mint module's querier route name. +func (AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// LegacyQuerierHandler returns the mint module sdk.Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return keeper.NewQuerier(am.keeper, legacyQuerierCdc) +} + +// RegisterServices registers a gRPC query service to respond to the +// module-specific gRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// InitGenesis performs genesis initialization for the mint module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + + am.keeper.InitGenesis(ctx, am.authKeeper, &genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the mint +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock returns the begin blocker for the mint module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + BeginBlocker(ctx, am.keeper) +} + +// AppModuleSimulation functions + +// GenerateGenesisState is a no-op. +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { + // no-op +} + +// ProposalContents doesn't return any content functions for governance proposals. +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RegisterStoreDecoder registers a decoder for mint module's types. +func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc) +} + +// WeightedOperations doesn't return any mint module operation. +func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} diff --git a/x/mint/module_test.go b/x/mint/module_test.go new file mode 100644 index 0000000..c738779 --- /dev/null +++ b/x/mint/module_test.go @@ -0,0 +1,37 @@ +package mint_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/simapp" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) + + app.InitChain( + abcitypes.RequestInitChain{ + AppStateBytes: stateBytes, + ChainId: "test-chain-id", + }, + ) + + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) + require.NotNil(t, acc) +} diff --git a/x/mint/simulation/decoder.go b/x/mint/simulation/decoder.go new file mode 100644 index 0000000..7cca7cf --- /dev/null +++ b/x/mint/simulation/decoder.go @@ -0,0 +1,26 @@ +package simulation + +import ( + "bytes" + "fmt" + + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/kv" +) + +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's +// Value to the corresponding mint type. +func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { + switch { + case bytes.Equal(kvA.Key, types.MintKey): + var minterA, minterB types.Minter + cdc.MustUnmarshal(kvA.Value, &minterA) + cdc.MustUnmarshal(kvB.Value, &minterB) + return fmt.Sprintf("%v\n%v", minterA, minterB) + default: + panic(fmt.Sprintf("invalid mint key %X", kvA.Key)) + } + } +} diff --git a/x/mint/simulation/decoder_test.go b/x/mint/simulation/decoder_test.go new file mode 100644 index 0000000..980f4c0 --- /dev/null +++ b/x/mint/simulation/decoder_test.go @@ -0,0 +1,56 @@ +package simulation_test + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/celestiaorg/celestia-app/x/mint/simulation" + "github.com/celestiaorg/celestia-app/x/mint/types" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" +) + +func TestDecodeStore(t *testing.T) { + cdc := simapp.MakeTestEncodingConfig().Codec + decoder := simulation.NewDecodeStore(cdc) + unixEpoch := time.Unix(0, 0).UTC() + minter := types.NewMinter(sdk.OneDec(), sdk.NewDec(15), &unixEpoch, sdk.DefaultBondDenom) + + kvPairs := kv.Pairs{ + Pairs: []kv.Pair{ + {Key: types.MintKey, Value: cdc.MustMarshal(&minter)}, + {Key: []byte{0x99}, Value: []byte{0x99}}, + }, + } + tests := []struct { + name string + expected string + expectPanic bool + }{ + { + name: "Minter", + expected: fmt.Sprintf("%v\n%v", minter, minter), + expectPanic: false, + }, + { + name: "other", + expected: "", + expectPanic: true, + }, + } + + for i, tt := range tests { + i, tt := i, tt + t.Run(tt.name, func(t *testing.T) { + if tt.expectPanic { + require.Panics(t, func() { decoder(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) + return + } + require.Equal(t, tt.expected, decoder(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) + }) + } +} diff --git a/x/mint/types/codec.go b/x/mint/types/codec.go new file mode 100644 index 0000000..a7067d9 --- /dev/null +++ b/x/mint/types/codec.go @@ -0,0 +1,13 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" +) + +var amino = codec.NewLegacyAmino() + +func init() { + cryptocodec.RegisterCrypto(amino) + amino.Seal() +} diff --git a/x/mint/types/constants.go b/x/mint/types/constants.go new file mode 100644 index 0000000..029b63c --- /dev/null +++ b/x/mint/types/constants.go @@ -0,0 +1,26 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +const ( + NanosecondsPerSecond = 1_000_000_000 + SecondsPerMinute = 60 + MinutesPerHour = 60 + HoursPerDay = 24 + // DaysPerYear is the mean length of the Gregorian calendar year. Note this + // value isn't 365 because 97 out of 400 years are leap years. See + // https://en.wikipedia.org/wiki/Year + DaysPerYear = 365.2425 + SecondsPerYear = int(SecondsPerMinute * MinutesPerHour * HoursPerDay * DaysPerYear) // 31,556,952 + NanosecondsPerYear = int(NanosecondsPerSecond * SecondsPerMinute * MinutesPerHour * HoursPerDay * DaysPerYear) // 31,556,952,000,000,000 + + InitialInflationRate = 0.08 + DisinflationRate = 0.1 + TargetInflationRate = 0.015 +) + +var ( + initalInflationRate = sdk.NewDecWithPrec(InitialInflationRate*1000, 3) + disinflationRate = sdk.NewDecWithPrec(DisinflationRate*1000, 3) + targetInflationRate = sdk.NewDecWithPrec(TargetInflationRate*1000, 3) +) diff --git a/x/mint/types/events.go b/x/mint/types/events.go new file mode 100644 index 0000000..9dea531 --- /dev/null +++ b/x/mint/types/events.go @@ -0,0 +1,8 @@ +package types + +const ( + EventTypeMint = ModuleName + + AttributeKeyInflationRate = "inflation_rate" + AttributeKeyAnnualProvisions = "annual_provisions" +) diff --git a/x/mint/types/expected_keepers.go b/x/mint/types/expected_keepers.go new file mode 100644 index 0000000..a0c4f35 --- /dev/null +++ b/x/mint/types/expected_keepers.go @@ -0,0 +1,27 @@ +package types // noalias + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// StakingKeeper defines the expected staking keeper. +type StakingKeeper interface { + StakingTokenSupply(ctx sdk.Context) math.Int +} + +// AccountKeeper defines the contract required for account APIs. +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + SetModuleAccount(sdk.Context, types.ModuleAccountI) + GetModuleAccount(ctx sdk.Context, moduleName string) types.ModuleAccountI +} + +// BankKeeper defines the contract needed to be fulfilled for banking and supply +// dependencies. +type BankKeeper interface { + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error + MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error +} diff --git a/x/mint/types/genesis.go b/x/mint/types/genesis.go new file mode 100644 index 0000000..4e8b926 --- /dev/null +++ b/x/mint/types/genesis.go @@ -0,0 +1,21 @@ +package types + +// NewGenesisState creates a new GenesisState object +func NewGenesisState(minter Minter) *GenesisState { + return &GenesisState{ + Minter: minter, + } +} + +// DefaultGenesisState creates a default GenesisState object +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Minter: DefaultMinter(), + } +} + +// ValidateGenesis validates the provided genesis state to ensure the +// expected invariants holds. +func ValidateGenesis(data GenesisState) error { + return data.Minter.Validate() +} diff --git a/x/mint/types/genesis.pb.go b/x/mint/types/genesis.pb.go new file mode 100644 index 0000000..cf8a6e9 --- /dev/null +++ b/x/mint/types/genesis.pb.go @@ -0,0 +1,322 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: celestia/mint/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// 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 + +// GenesisState defines the mint module's genesis state. +type GenesisState struct { + // minter is a space for holding current inflation information. + Minter Minter `protobuf:"bytes,1,opt,name=minter,proto3" json:"minter"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_1932cb996a3161e7, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetMinter() Minter { + if m != nil { + return m.Minter + } + return Minter{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "celestia.mint.v1.GenesisState") +} + +func init() { proto.RegisterFile("celestia/mint/v1/genesis.proto", fileDescriptor_1932cb996a3161e7) } + +var fileDescriptor_1932cb996a3161e7 = []byte{ + // 197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0x4e, 0xcd, 0x49, + 0x2d, 0x2e, 0xc9, 0x4c, 0xd4, 0xcf, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, + 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x80, 0xc9, 0xeb, 0x81, + 0xe4, 0xf5, 0xca, 0x0c, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x92, 0xfa, 0x20, 0x16, 0x44, + 0x9d, 0x94, 0x34, 0x86, 0x39, 0x60, 0xf5, 0x60, 0x49, 0x25, 0x37, 0x2e, 0x1e, 0x77, 0x88, 0xa9, + 0xc1, 0x25, 0x89, 0x25, 0xa9, 0x42, 0x66, 0x5c, 0x6c, 0x20, 0xd9, 0xd4, 0x22, 0x09, 0x46, 0x05, + 0x46, 0x0d, 0x6e, 0x23, 0x09, 0x3d, 0x74, 0x5b, 0xf4, 0x7c, 0xc1, 0xf2, 0x4e, 0x2c, 0x27, 0xee, + 0xc9, 0x33, 0x04, 0x41, 0x55, 0x3b, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, + 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, + 0x43, 0x94, 0x41, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xcc, 0xac, + 0xfc, 0xa2, 0x74, 0x38, 0x5b, 0x37, 0xb1, 0xa0, 0x40, 0xbf, 0x02, 0xe2, 0xb6, 0x92, 0xca, 0x82, + 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0xd3, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xfa, 0xc5, + 0x86, 0x01, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Minter.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Minter.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Minter", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Minter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/mint/types/keys.go b/x/mint/types/keys.go new file mode 100644 index 0000000..2b8bede --- /dev/null +++ b/x/mint/types/keys.go @@ -0,0 +1,20 @@ +package types + +// MintKey is the key to use for the keeper store. +var MintKey = []byte{0x00} + +const ( + // ModuleName is the name of the mint module. + ModuleName = "mint" + + // StoreKey is the default store key for mint + StoreKey = ModuleName + + // QuerierRoute is the querier route for the mint store. + QuerierRoute = StoreKey + + // Query endpoints supported by the mint querier + QueryInflationRate = "inflation_rate" + QueryAnnualProvisions = "annual_provisions" + QueryGenesisTime = "genesis_time" +) diff --git a/x/mint/types/mint.pb.go b/x/mint/types/mint.pb.go new file mode 100644 index 0000000..db7322c --- /dev/null +++ b/x/mint/types/mint.pb.go @@ -0,0 +1,554 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: celestia/mint/v1/mint.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "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 + +// Minter represents the mint state. +type Minter struct { + // InflationRate is the rate at which new tokens should be minted for the + // current year. For example if InflationRate=0.1, then 10% of the total + // supply will be minted over the course of the year. + InflationRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=inflation_rate,json=inflationRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"inflation_rate"` + // AnnualProvisions is the total number of tokens to be minted in the current + // year due to inflation. + AnnualProvisions github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=annual_provisions,json=annualProvisions,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"annual_provisions"` + // GenesisTime is the timestamp of the genesis block. + GenesisTime *time.Time `protobuf:"bytes,3,opt,name=genesis_time,json=genesisTime,proto3,stdtime" json:"genesis_time,omitempty"` + // PreviousBlockTime is the timestamp of the previous block. + PreviousBlockTime *time.Time `protobuf:"bytes,4,opt,name=previous_block_time,json=previousBlockTime,proto3,stdtime" json:"previous_block_time,omitempty"` + // BondDenom is the denomination of the token that should be minted. + BondDenom string `protobuf:"bytes,5,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty"` +} + +func (m *Minter) Reset() { *m = Minter{} } +func (m *Minter) String() string { return proto.CompactTextString(m) } +func (*Minter) ProtoMessage() {} +func (*Minter) Descriptor() ([]byte, []int) { + return fileDescriptor_962d7cf1c9c59571, []int{0} +} +func (m *Minter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Minter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Minter.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 *Minter) XXX_Merge(src proto.Message) { + xxx_messageInfo_Minter.Merge(m, src) +} +func (m *Minter) XXX_Size() int { + return m.Size() +} +func (m *Minter) XXX_DiscardUnknown() { + xxx_messageInfo_Minter.DiscardUnknown(m) +} + +var xxx_messageInfo_Minter proto.InternalMessageInfo + +func (m *Minter) GetGenesisTime() *time.Time { + if m != nil { + return m.GenesisTime + } + return nil +} + +func (m *Minter) GetPreviousBlockTime() *time.Time { + if m != nil { + return m.PreviousBlockTime + } + return nil +} + +func (m *Minter) GetBondDenom() string { + if m != nil { + return m.BondDenom + } + return "" +} + +func init() { + proto.RegisterType((*Minter)(nil), "celestia.mint.v1.Minter") +} + +func init() { proto.RegisterFile("celestia/mint/v1/mint.proto", fileDescriptor_962d7cf1c9c59571) } + +var fileDescriptor_962d7cf1c9c59571 = []byte{ + // 379 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x52, 0xb1, 0x6e, 0xdb, 0x30, + 0x10, 0x95, 0x6a, 0xd7, 0x80, 0xe9, 0xb6, 0xb0, 0xd5, 0x0e, 0xaa, 0x8b, 0x4a, 0x46, 0x87, 0xc2, + 0x8b, 0xa5, 0xba, 0x59, 0x33, 0x29, 0x9e, 0x02, 0x04, 0x30, 0x84, 0x4c, 0x59, 0x04, 0x4a, 0xa6, + 0x15, 0xc2, 0x12, 0x4f, 0x10, 0x29, 0x21, 0xf9, 0x89, 0xc0, 0x1f, 0x93, 0x8f, 0xf0, 0x68, 0x64, + 0x0a, 0x32, 0x38, 0x81, 0xfd, 0x23, 0x01, 0x45, 0xc9, 0xc8, 0x98, 0x21, 0x13, 0x79, 0xef, 0xdd, + 0xbd, 0xbb, 0x7b, 0x38, 0xf4, 0x2b, 0x22, 0x09, 0xe1, 0x82, 0x62, 0x37, 0xa5, 0x4c, 0xb8, 0xe5, + 0xb4, 0x7a, 0x9d, 0x2c, 0x07, 0x01, 0x46, 0xbf, 0x21, 0x9d, 0x0a, 0x2c, 0xa7, 0xc3, 0x1f, 0x31, + 0xc4, 0x50, 0x91, 0xae, 0xfc, 0xa9, 0xbc, 0xe1, 0xcf, 0x08, 0x78, 0x0a, 0x3c, 0x50, 0x84, 0x0a, + 0x6a, 0xca, 0x8e, 0x01, 0xe2, 0x84, 0xb8, 0x55, 0x14, 0x16, 0x4b, 0x57, 0xd0, 0x94, 0x70, 0x81, + 0xd3, 0x4c, 0x25, 0xfc, 0xb9, 0x6b, 0xa1, 0xce, 0x05, 0x65, 0x82, 0xe4, 0x46, 0x84, 0xbe, 0x51, + 0xb6, 0x4c, 0xb0, 0xa0, 0xc0, 0x82, 0x1c, 0x0b, 0x62, 0xea, 0x23, 0x7d, 0xdc, 0xf5, 0x4e, 0x37, + 0x3b, 0x5b, 0x7b, 0xda, 0xd9, 0x7f, 0x63, 0x2a, 0xae, 0x8b, 0xd0, 0x89, 0x20, 0xad, 0x9b, 0xd4, + 0xcf, 0x84, 0x2f, 0x56, 0xae, 0xb8, 0xcd, 0x08, 0x77, 0x66, 0x24, 0x7a, 0xb8, 0x9f, 0xa0, 0x7a, + 0x86, 0x19, 0x89, 0xfc, 0xaf, 0x47, 0x4d, 0x1f, 0x0b, 0x62, 0x50, 0x34, 0xc0, 0x8c, 0x15, 0x38, + 0x91, 0xd3, 0x96, 0x94, 0x53, 0x60, 0xdc, 0xfc, 0xf4, 0x01, 0x7d, 0xfa, 0x4a, 0x76, 0x7e, 0x54, + 0x35, 0xce, 0xd0, 0x97, 0x98, 0x30, 0xc2, 0x29, 0x0f, 0xe4, 0xd6, 0x66, 0x6b, 0xa4, 0x8f, 0x7b, + 0xff, 0x87, 0x8e, 0xb2, 0xc4, 0x69, 0x2c, 0x71, 0x2e, 0x1b, 0x4b, 0xbc, 0xf6, 0xfa, 0xd9, 0xd6, + 0xfd, 0x5e, 0x5d, 0x25, 0x71, 0x63, 0x8e, 0xbe, 0x67, 0x39, 0x29, 0x29, 0x14, 0x3c, 0x08, 0x13, + 0x88, 0x56, 0x4a, 0xab, 0xfd, 0x4e, 0xad, 0x41, 0x53, 0xec, 0xc9, 0xda, 0x4a, 0xf1, 0x37, 0x42, + 0x21, 0xb0, 0x45, 0xb0, 0x20, 0x0c, 0x52, 0xf3, 0xb3, 0x5c, 0xdd, 0xef, 0x4a, 0x64, 0x26, 0x01, + 0xef, 0x7c, 0xb3, 0xb7, 0xf4, 0xed, 0xde, 0xd2, 0x5f, 0xf6, 0x96, 0xbe, 0x3e, 0x58, 0xda, 0xf6, + 0x60, 0x69, 0x8f, 0x07, 0x4b, 0xbb, 0xfa, 0xf7, 0xd6, 0x97, 0xfa, 0x32, 0x20, 0x8f, 0x8f, 0xff, + 0x09, 0xce, 0x32, 0xf7, 0x46, 0x1d, 0x52, 0xe5, 0x52, 0xd8, 0xa9, 0xe6, 0x3a, 0x79, 0x0d, 0x00, + 0x00, 0xff, 0xff, 0xc0, 0x3b, 0x5f, 0x08, 0x66, 0x02, 0x00, 0x00, +} + +func (m *Minter) 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 *Minter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Minter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BondDenom) > 0 { + i -= len(m.BondDenom) + copy(dAtA[i:], m.BondDenom) + i = encodeVarintMint(dAtA, i, uint64(len(m.BondDenom))) + i-- + dAtA[i] = 0x2a + } + if m.PreviousBlockTime != nil { + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.PreviousBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.PreviousBlockTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintMint(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x22 + } + if m.GenesisTime != nil { + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.GenesisTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.GenesisTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintMint(dAtA, i, uint64(n2)) + i-- + dAtA[i] = 0x1a + } + { + size := m.AnnualProvisions.Size() + i -= size + if _, err := m.AnnualProvisions.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintMint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.InflationRate.Size() + i -= size + if _, err := m.InflationRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintMint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintMint(dAtA []byte, offset int, v uint64) int { + offset -= sovMint(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Minter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.InflationRate.Size() + n += 1 + l + sovMint(uint64(l)) + l = m.AnnualProvisions.Size() + n += 1 + l + sovMint(uint64(l)) + if m.GenesisTime != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.GenesisTime) + n += 1 + l + sovMint(uint64(l)) + } + if m.PreviousBlockTime != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.PreviousBlockTime) + n += 1 + l + sovMint(uint64(l)) + } + l = len(m.BondDenom) + if l > 0 { + n += 1 + l + sovMint(uint64(l)) + } + return n +} + +func sovMint(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMint(x uint64) (n int) { + return sovMint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Minter) 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 ErrIntOverflowMint + } + 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: Minter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Minter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InflationRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + 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 ErrInvalidLengthMint + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InflationRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AnnualProvisions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + 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 ErrInvalidLengthMint + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AnnualProvisions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GenesisTime == nil { + m.GenesisTime = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.GenesisTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousBlockTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PreviousBlockTime == nil { + m.PreviousBlockTime = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.PreviousBlockTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BondDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + 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 ErrInvalidLengthMint + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BondDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMint(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMint + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMint(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, ErrIntOverflowMint + } + 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, ErrIntOverflowMint + } + 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, ErrIntOverflowMint + } + 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, ErrInvalidLengthMint + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupMint + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthMint + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthMint = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMint = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupMint = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/mint/types/minter.go b/x/mint/types/minter.go new file mode 100644 index 0000000..e0d2b53 --- /dev/null +++ b/x/mint/types/minter.go @@ -0,0 +1,76 @@ +package types + +import ( + "fmt" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewMinter returns a new Minter object. +func NewMinter(inflationRate sdk.Dec, annualProvisions sdk.Dec, genesisTime *time.Time, bondDenom string) Minter { + return Minter{ + InflationRate: inflationRate, + AnnualProvisions: annualProvisions, + GenesisTime: genesisTime, + BondDenom: bondDenom, + } +} + +// DefaultMinter returns a Minter object with default values. +func DefaultMinter() Minter { + unixEpoch := time.Unix(0, 0).UTC() + return NewMinter(initalInflationRate, sdk.NewDec(0), &unixEpoch, sdk.DefaultBondDenom) +} + +// Validate returns an error if the minter is invalid. +func (m Minter) Validate() error { + if m.InflationRate.IsNegative() { + return fmt.Errorf("inflation rate %v should be positive", m.InflationRate.String()) + } + if m.AnnualProvisions.IsNegative() { + return fmt.Errorf("annual provisions %v should be positive", m.AnnualProvisions.String()) + } + if m.BondDenom == "" { + return fmt.Errorf("bond denom should not be empty string") + } + return nil +} + +// CalculateInflationRate returns the inflation rate for the current year depending on +// the current block height in context. The inflation rate is expected to +// decrease every year according to the schedule specified in the README. +func (m Minter) CalculateInflationRate(ctx sdk.Context) sdk.Dec { + years := yearsSinceGenesis(*m.GenesisTime, ctx.BlockTime()) + inflationRate := initalInflationRate.Mul(sdk.OneDec().Sub(disinflationRate).Power(uint64(years))) + + if inflationRate.LT(targetInflationRate) { + return targetInflationRate + } + return inflationRate +} + +// CalculateAnnualProvisions returns the total number of tokens that should be +// minted due to inflation for the current year. +func (m Minter) CalculateAnnualProvisions(totalSupply math.Int) sdk.Dec { + return m.InflationRate.MulInt(totalSupply) +} + +// CalculateBlockProvision returns the total number of coins that should be +// minted due to inflation for the current block. +func (m Minter) CalculateBlockProvision(current time.Time, previous time.Time) sdk.Coin { + timeElapsed := current.Sub(previous).Nanoseconds() + portionOfYear := sdk.NewDec(int64(timeElapsed)).Quo(sdk.NewDec(int64(NanosecondsPerYear))) + blockProvision := m.AnnualProvisions.Mul(portionOfYear) + return sdk.NewCoin(m.BondDenom, blockProvision.TruncateInt()) +} + +// yearsSinceGenesis returns the number of years that have passed between +// genesis and current (rounded down). +func yearsSinceGenesis(genesis time.Time, current time.Time) (years int64) { + if current.Before(genesis) { + return 0 + } + return current.Sub(genesis).Nanoseconds() / int64(NanosecondsPerYear) +} diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go new file mode 100644 index 0000000..7fcaea6 --- /dev/null +++ b/x/mint/types/minter_test.go @@ -0,0 +1,259 @@ +package types + +import ( + fmt "fmt" + "math/rand" + "testing" + time "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestCalculateInflationRate(t *testing.T) { + minter := DefaultMinter() + genesisTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) + minter.GenesisTime = &genesisTime + + type testCase struct { + year int + want float64 + } + + testCases := []testCase{ + {0, 0.08}, + {1, 0.072}, + {2, 0.0648}, + {3, 0.05832}, + {4, 0.052488}, + {5, 0.0472392}, + {6, 0.04251528}, + {7, 0.038263752}, + {8, 0.0344373768}, + {9, 0.03099363912}, + {10, 0.027894275208}, + {11, 0.0251048476872}, + {12, 0.02259436291848}, + {13, 0.020334926626632}, + {14, 0.0183014339639688}, + {15, 0.01647129056757192}, + {16, 0.0150}, + {17, 0.0150}, + {18, 0.0150}, + {19, 0.0150}, + {20, 0.0150}, + {21, 0.0150}, + {22, 0.0150}, + {23, 0.0150}, + {24, 0.0150}, + {25, 0.0150}, + {26, 0.0150}, + {27, 0.0150}, + {28, 0.0150}, + {29, 0.0150}, + {30, 0.0150}, + {31, 0.0150}, + {32, 0.0150}, + {33, 0.0150}, + {34, 0.0150}, + {35, 0.0150}, + {36, 0.0150}, + {37, 0.0150}, + {38, 0.0150}, + {39, 0.0150}, + {40, 0.0150}, + } + + for _, tc := range testCases { + years := time.Duration(tc.year * NanosecondsPerYear * int(time.Nanosecond)) + blockTime := genesisTime.Add(years) + ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil).WithBlockTime(blockTime) + inflationRate := minter.CalculateInflationRate(ctx) + got, err := inflationRate.Float64() + assert.NoError(t, err) + assert.Equal(t, tc.want, got, "want %v got %v year %v blockTime %v", tc.want, got, tc.year, blockTime) + } +} + +func TestCalculateBlockProvision(t *testing.T) { + minter := DefaultMinter() + current := time.Date(2023, 1, 2, 0, 0, 0, 0, time.UTC) + blockInterval := 15 * time.Second + totalSupply := sdk.NewDec(1_000_000_000_000) // 1 trillion utia + annualProvisions := totalSupply.Mul(initalInflationRate) // 80 billion utia + + type testCase struct { + name string + annualProvisions sdk.Dec + current time.Time + previous time.Time + want sdk.Coin + } + + testCases := []testCase{ + { + name: "one 15 second block during the first year", + annualProvisions: annualProvisions, + current: current, + previous: current.Add(-blockInterval), + // 80 billion utia (annual provisions) * 15 (seconds) / 31,556,952 (seconds per year) = 38026.48620817 which truncates to 38026 utia + want: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(38026)), + }, + { + name: "one 30 second block during the first year", + annualProvisions: annualProvisions, + current: current, + previous: current.Add(-2 * blockInterval), + // 80 billion utia (annual provisions) * 30 (seconds) / 31,556,952 (seconds per year) = 76052.97241635 which truncates to 76052 utia + want: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(76052)), + }, + } + for _, tc := range testCases { + minter.AnnualProvisions = tc.annualProvisions + got := minter.CalculateBlockProvision(tc.current, tc.previous) + require.True(t, tc.want.IsEqual(got), "want %v got %v", tc.want, got) + } +} + +// TestCalculateBlockProvisionError verifies that the error for total block +// provisions in a year is less than .01 +func TestCalculateBlockProvisionError(t *testing.T) { + oneYear, err := time.ParseDuration(fmt.Sprintf("%vns", NanosecondsPerYear)) + assert.NoError(t, err) + + minter := DefaultMinter() + current := time.Date(2023, 1, 2, 0, 0, 0, 0, time.UTC) + end := current.Add(oneYear) + + totalSupply := sdk.NewDec(1_000_000_000_000) // 1 trillion utia + annualProvisions := totalSupply.Mul(initalInflationRate) // 80 billion utia + minter.AnnualProvisions = annualProvisions + totalBlockProvisions := sdk.NewDec(0) + for current.Before(end) { + blockInterval := randomBlockInterval() + previous := current + current = current.Add(blockInterval) + got := minter.CalculateBlockProvision(current, previous) + totalBlockProvisions = totalBlockProvisions.Add(sdk.NewDecFromInt(got.Amount)) + } + + gotError := totalBlockProvisions.Sub(annualProvisions).Abs().Quo(annualProvisions) + wantError := sdk.NewDecWithPrec(1, 2) // .01 + assert.True(t, gotError.LTE(wantError)) +} + +func randomBlockInterval() time.Duration { + min := (14 * time.Second).Nanoseconds() + max := (16 * time.Second).Nanoseconds() + return time.Duration(randInRange(min, max)) +} + +// randInRange returns a random number in the range (min, max) inclusive. +func randInRange(min int64, max int64) int64 { + return rand.Int63n(max-min) + min +} + +func BenchmarkCalculateBlockProvision(b *testing.B) { + b.ReportAllocs() + minter := DefaultMinter() + + s1 := rand.NewSource(100) + r1 := rand.New(s1) + minter.AnnualProvisions = sdk.NewDec(r1.Int63n(1000000)) + current := time.Unix(r1.Int63n(1000000), 0) + previous := current.Add(time.Second * 15) + + for n := 0; n < b.N; n++ { + minter.CalculateBlockProvision(current, previous) + } +} + +func BenchmarkCalculateInflationRate(b *testing.B) { + b.ReportAllocs() + minter := DefaultMinter() + + for n := 0; n < b.N; n++ { + ctx := sdk.NewContext(nil, tmproto.Header{Height: int64(n)}, false, nil) + minter.CalculateInflationRate(ctx) + } +} + +func BenchmarkCalculateAnnualProvisions(b *testing.B) { + b.ReportAllocs() + minter := DefaultMinter() + totalSupply := sdk.NewInt(100000000000000) + + for n := 0; n < b.N; n++ { + minter.CalculateAnnualProvisions(totalSupply) + } +} + +func Test_yearsSinceGenesis(t *testing.T) { + type testCase struct { + name string + current time.Time + want int64 + } + + genesis := time.Date(2023, 1, 1, 12, 30, 15, 0, time.UTC) // 2023-01-01T12:30:15Z + oneDay, err := time.ParseDuration("24h") + assert.NoError(t, err) + oneWeek := oneDay * 7 + oneMonth := oneDay * 30 + oneYear, err := time.ParseDuration(fmt.Sprintf("%vns", NanosecondsPerYear)) + assert.NoError(t, err) + twoYears := 2 * oneYear + tenYears := 10 * oneYear + tenYearsOneMonth := tenYears + oneMonth + + testCases := []testCase{ + { + name: "one day after genesis", + current: genesis.Add(oneDay), + want: 0, + }, + { + name: "one day before genesis", + current: genesis.Add(-oneDay), + want: 0, + }, + { + name: "one week after genesis", + current: genesis.Add(oneWeek), + want: 0, + }, + { + name: "one month after genesis", + current: genesis.Add(oneMonth), + want: 0, + }, + { + name: "one year after genesis", + current: genesis.Add(oneYear), + want: 1, + }, + { + name: "two years after genesis", + current: genesis.Add(twoYears), + want: 2, + }, + { + name: "ten years after genesis", + current: genesis.Add(tenYears), + want: 10, + }, + { + name: "ten years and one month after genesis", + current: genesis.Add(tenYearsOneMonth), + want: 10, + }, + } + + for _, tc := range testCases { + got := yearsSinceGenesis(genesis, tc.current) + assert.Equal(t, tc.want, got, tc.name) + } +} diff --git a/x/mint/types/query.pb.go b/x/mint/types/query.pb.go new file mode 100644 index 0000000..27ed105 --- /dev/null +++ b/x/mint/types/query.pb.go @@ -0,0 +1,1212 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: celestia/mint/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/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/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 + +// QueryInflationRateRequest is the request type for the Query/InflationRate RPC method. +type QueryInflationRateRequest struct { +} + +func (m *QueryInflationRateRequest) Reset() { *m = QueryInflationRateRequest{} } +func (m *QueryInflationRateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryInflationRateRequest) ProtoMessage() {} +func (*QueryInflationRateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{0} +} +func (m *QueryInflationRateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryInflationRateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryInflationRateRequest.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 *QueryInflationRateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryInflationRateRequest.Merge(m, src) +} +func (m *QueryInflationRateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryInflationRateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryInflationRateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryInflationRateRequest proto.InternalMessageInfo + +// QueryInflationRateResponse is the response type for the Query/InflationRate RPC +// method. +type QueryInflationRateResponse struct { + // InflationRate is the current inflation rate. + InflationRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=inflation_rate,json=inflationRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"inflation_rate"` +} + +func (m *QueryInflationRateResponse) Reset() { *m = QueryInflationRateResponse{} } +func (m *QueryInflationRateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryInflationRateResponse) ProtoMessage() {} +func (*QueryInflationRateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{1} +} +func (m *QueryInflationRateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryInflationRateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryInflationRateResponse.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 *QueryInflationRateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryInflationRateResponse.Merge(m, src) +} +func (m *QueryInflationRateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryInflationRateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryInflationRateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryInflationRateResponse proto.InternalMessageInfo + +// QueryAnnualProvisionsRequest is the request type for the +// Query/AnnualProvisions RPC method. +type QueryAnnualProvisionsRequest struct { +} + +func (m *QueryAnnualProvisionsRequest) Reset() { *m = QueryAnnualProvisionsRequest{} } +func (m *QueryAnnualProvisionsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAnnualProvisionsRequest) ProtoMessage() {} +func (*QueryAnnualProvisionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{2} +} +func (m *QueryAnnualProvisionsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAnnualProvisionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAnnualProvisionsRequest.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 *QueryAnnualProvisionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAnnualProvisionsRequest.Merge(m, src) +} +func (m *QueryAnnualProvisionsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAnnualProvisionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAnnualProvisionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAnnualProvisionsRequest proto.InternalMessageInfo + +// QueryAnnualProvisionsResponse is the response type for the +// Query/AnnualProvisions RPC method. +type QueryAnnualProvisionsResponse struct { + // AnnualProvisions is the current annual provisions. + AnnualProvisions github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=annual_provisions,json=annualProvisions,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"annual_provisions"` +} + +func (m *QueryAnnualProvisionsResponse) Reset() { *m = QueryAnnualProvisionsResponse{} } +func (m *QueryAnnualProvisionsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAnnualProvisionsResponse) ProtoMessage() {} +func (*QueryAnnualProvisionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{3} +} +func (m *QueryAnnualProvisionsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAnnualProvisionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAnnualProvisionsResponse.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 *QueryAnnualProvisionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAnnualProvisionsResponse.Merge(m, src) +} +func (m *QueryAnnualProvisionsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAnnualProvisionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAnnualProvisionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAnnualProvisionsResponse proto.InternalMessageInfo + +// QueryGenesisTimeRequest is the request type for the Query/GenesisTime RPC method. +type QueryGenesisTimeRequest struct { +} + +func (m *QueryGenesisTimeRequest) Reset() { *m = QueryGenesisTimeRequest{} } +func (m *QueryGenesisTimeRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGenesisTimeRequest) ProtoMessage() {} +func (*QueryGenesisTimeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{4} +} +func (m *QueryGenesisTimeRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGenesisTimeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGenesisTimeRequest.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 *QueryGenesisTimeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGenesisTimeRequest.Merge(m, src) +} +func (m *QueryGenesisTimeRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGenesisTimeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGenesisTimeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGenesisTimeRequest proto.InternalMessageInfo + +// QueryGenesisTimeResponse is the response type for the Query/GenesisTime RPC method. +type QueryGenesisTimeResponse struct { + // GenesisTime is the timestamp associated with the first block. + GenesisTime *time.Time `protobuf:"bytes,1,opt,name=genesis_time,json=genesisTime,proto3,stdtime" json:"genesis_time,omitempty"` +} + +func (m *QueryGenesisTimeResponse) Reset() { *m = QueryGenesisTimeResponse{} } +func (m *QueryGenesisTimeResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGenesisTimeResponse) ProtoMessage() {} +func (*QueryGenesisTimeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a1ed5b0ae449a133, []int{5} +} +func (m *QueryGenesisTimeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGenesisTimeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGenesisTimeResponse.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 *QueryGenesisTimeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGenesisTimeResponse.Merge(m, src) +} +func (m *QueryGenesisTimeResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGenesisTimeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGenesisTimeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGenesisTimeResponse proto.InternalMessageInfo + +func (m *QueryGenesisTimeResponse) GetGenesisTime() *time.Time { + if m != nil { + return m.GenesisTime + } + return nil +} + +func init() { + proto.RegisterType((*QueryInflationRateRequest)(nil), "celestia.mint.v1.QueryInflationRateRequest") + proto.RegisterType((*QueryInflationRateResponse)(nil), "celestia.mint.v1.QueryInflationRateResponse") + proto.RegisterType((*QueryAnnualProvisionsRequest)(nil), "celestia.mint.v1.QueryAnnualProvisionsRequest") + proto.RegisterType((*QueryAnnualProvisionsResponse)(nil), "celestia.mint.v1.QueryAnnualProvisionsResponse") + proto.RegisterType((*QueryGenesisTimeRequest)(nil), "celestia.mint.v1.QueryGenesisTimeRequest") + proto.RegisterType((*QueryGenesisTimeResponse)(nil), "celestia.mint.v1.QueryGenesisTimeResponse") +} + +func init() { proto.RegisterFile("celestia/mint/v1/query.proto", fileDescriptor_a1ed5b0ae449a133) } + +var fileDescriptor_a1ed5b0ae449a133 = []byte{ + // 499 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x4d, 0x6e, 0x13, 0x31, + 0x1c, 0xc5, 0x63, 0xbe, 0x16, 0x4e, 0x8b, 0x82, 0x85, 0x44, 0x3b, 0x0d, 0x13, 0x98, 0x8a, 0xaa, + 0xa5, 0xd4, 0x26, 0xe5, 0x04, 0x04, 0x24, 0x04, 0x2b, 0x88, 0xca, 0x06, 0x16, 0x91, 0x13, 0x5c, + 0x63, 0x91, 0xb1, 0xdd, 0xb1, 0x27, 0xa2, 0x12, 0x2b, 0x2e, 0x40, 0x25, 0x16, 0x1c, 0x80, 0xcb, + 0x74, 0x59, 0x89, 0x0d, 0xb0, 0x28, 0x28, 0xe1, 0x20, 0x68, 0x3c, 0x9e, 0x90, 0xaf, 0x91, 0x22, + 0x56, 0x71, 0xe6, 0xfd, 0xe7, 0xff, 0x7e, 0xe3, 0xf7, 0x60, 0xbd, 0xc7, 0xfa, 0xcc, 0x58, 0x41, + 0x49, 0x2c, 0xa4, 0x25, 0x83, 0x26, 0x39, 0x4a, 0x59, 0x72, 0x8c, 0x75, 0xa2, 0xac, 0x42, 0xb5, + 0x42, 0xc5, 0x99, 0x8a, 0x07, 0xcd, 0xe0, 0x3a, 0x57, 0x5c, 0x39, 0x91, 0x64, 0xa7, 0x7c, 0x2e, + 0xa8, 0x73, 0xa5, 0x78, 0x9f, 0x11, 0xaa, 0x05, 0xa1, 0x52, 0x2a, 0x4b, 0xad, 0x50, 0xd2, 0x78, + 0x75, 0x63, 0xce, 0xc3, 0x6d, 0xcb, 0xc5, 0x86, 0x7f, 0xd5, 0xfd, 0xeb, 0xa6, 0x87, 0xc4, 0x8a, + 0x98, 0x19, 0x4b, 0x63, 0x9d, 0x0f, 0x44, 0x1b, 0x70, 0xfd, 0x45, 0x86, 0xf4, 0x54, 0x1e, 0xf6, + 0xdd, 0xda, 0x36, 0xb5, 0xac, 0xcd, 0x8e, 0x52, 0x66, 0x6c, 0x64, 0x60, 0xb0, 0x48, 0x34, 0x5a, + 0x49, 0xc3, 0xd0, 0x4b, 0x78, 0x55, 0x14, 0x42, 0x27, 0xa1, 0x96, 0xad, 0x81, 0x5b, 0x60, 0x7b, + 0xa5, 0x85, 0x4f, 0xcf, 0x1b, 0x95, 0x9f, 0xe7, 0x8d, 0x2d, 0x2e, 0xec, 0xdb, 0xb4, 0x8b, 0x7b, + 0x2a, 0x26, 0x3d, 0x65, 0x62, 0x65, 0xfc, 0xcf, 0x9e, 0x79, 0xf3, 0x8e, 0xd8, 0x63, 0xcd, 0x0c, + 0x7e, 0xcc, 0x7a, 0xed, 0x55, 0x31, 0xb9, 0x3e, 0x0a, 0x61, 0xdd, 0x99, 0x3e, 0x94, 0x32, 0xa5, + 0xfd, 0xe7, 0x89, 0x1a, 0x08, 0x93, 0x7d, 0x6e, 0x01, 0xf5, 0x01, 0xde, 0x2c, 0xd1, 0x3d, 0xd7, + 0x6b, 0x78, 0x8d, 0x3a, 0xad, 0xa3, 0xc7, 0xe2, 0x7f, 0xa2, 0xd5, 0xe8, 0x8c, 0x49, 0xb4, 0x0e, + 0x6f, 0x38, 0xf7, 0x27, 0x4c, 0x32, 0x23, 0xcc, 0x81, 0x88, 0xc7, 0xb7, 0xd5, 0x81, 0x6b, 0xf3, + 0x92, 0x67, 0x7a, 0x04, 0x57, 0x78, 0xfe, 0xb8, 0x93, 0x25, 0xe0, 0x70, 0xaa, 0xfb, 0x01, 0xce, + 0xe3, 0xc1, 0x45, 0x3c, 0xf8, 0xa0, 0x88, 0xa7, 0x75, 0xe9, 0xe4, 0x57, 0x03, 0xb4, 0xab, 0xfc, + 0xdf, 0xb2, 0xfd, 0x1f, 0x17, 0xe1, 0x65, 0xe7, 0x80, 0xbe, 0x00, 0xb8, 0x3a, 0x15, 0x0a, 0xda, + 0xc5, 0xb3, 0x65, 0xc2, 0xa5, 0xb9, 0x06, 0xf7, 0x96, 0x1b, 0xce, 0xd9, 0xa3, 0xdd, 0x8f, 0xdf, + 0xfe, 0x7c, 0xbe, 0x70, 0x07, 0x6d, 0x16, 0x57, 0xe5, 0x7b, 0xd6, 0x65, 0x96, 0x36, 0xc9, 0x74, + 0x05, 0xd0, 0x57, 0x00, 0x6b, 0xb3, 0xc9, 0x20, 0x5c, 0xe2, 0x57, 0x12, 0x71, 0x40, 0x96, 0x9e, + 0xf7, 0x88, 0xd8, 0x21, 0x6e, 0xa3, 0xad, 0x85, 0x88, 0x73, 0x6d, 0x40, 0x9f, 0x00, 0xac, 0x4e, + 0xc4, 0x84, 0x76, 0x4a, 0x0c, 0xe7, 0x53, 0x0e, 0xee, 0x2e, 0x33, 0xea, 0xb1, 0x76, 0x1c, 0xd6, + 0x26, 0xba, 0xbd, 0x10, 0x6b, 0xb2, 0x10, 0xad, 0x67, 0xa7, 0xc3, 0x10, 0x9c, 0x0d, 0x43, 0xf0, + 0x7b, 0x18, 0x82, 0x93, 0x51, 0x58, 0x39, 0x1b, 0x85, 0x95, 0xef, 0xa3, 0xb0, 0xf2, 0xea, 0xfe, + 0x64, 0x57, 0xbd, 0xb5, 0x4a, 0xf8, 0xf8, 0xbc, 0x47, 0xb5, 0x26, 0xef, 0xf3, 0xd5, 0xae, 0xb9, + 0xdd, 0x2b, 0xae, 0x4e, 0x0f, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd1, 0xb5, 0x7b, 0x2f, 0x7e, + 0x04, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // InflationRate returns the current inflation rate. + InflationRate(ctx context.Context, in *QueryInflationRateRequest, opts ...grpc.CallOption) (*QueryInflationRateResponse, error) + // AnnualProvisions returns the current annual provisions. + AnnualProvisions(ctx context.Context, in *QueryAnnualProvisionsRequest, opts ...grpc.CallOption) (*QueryAnnualProvisionsResponse, error) + // GenesisTime returns the genesis time. + GenesisTime(ctx context.Context, in *QueryGenesisTimeRequest, opts ...grpc.CallOption) (*QueryGenesisTimeResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) InflationRate(ctx context.Context, in *QueryInflationRateRequest, opts ...grpc.CallOption) (*QueryInflationRateResponse, error) { + out := new(QueryInflationRateResponse) + err := c.cc.Invoke(ctx, "/celestia.mint.v1.Query/InflationRate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AnnualProvisions(ctx context.Context, in *QueryAnnualProvisionsRequest, opts ...grpc.CallOption) (*QueryAnnualProvisionsResponse, error) { + out := new(QueryAnnualProvisionsResponse) + err := c.cc.Invoke(ctx, "/celestia.mint.v1.Query/AnnualProvisions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GenesisTime(ctx context.Context, in *QueryGenesisTimeRequest, opts ...grpc.CallOption) (*QueryGenesisTimeResponse, error) { + out := new(QueryGenesisTimeResponse) + err := c.cc.Invoke(ctx, "/celestia.mint.v1.Query/GenesisTime", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // InflationRate returns the current inflation rate. + InflationRate(context.Context, *QueryInflationRateRequest) (*QueryInflationRateResponse, error) + // AnnualProvisions returns the current annual provisions. + AnnualProvisions(context.Context, *QueryAnnualProvisionsRequest) (*QueryAnnualProvisionsResponse, error) + // GenesisTime returns the genesis time. + GenesisTime(context.Context, *QueryGenesisTimeRequest) (*QueryGenesisTimeResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) InflationRate(ctx context.Context, req *QueryInflationRateRequest) (*QueryInflationRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InflationRate not implemented") +} +func (*UnimplementedQueryServer) AnnualProvisions(ctx context.Context, req *QueryAnnualProvisionsRequest) (*QueryAnnualProvisionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AnnualProvisions not implemented") +} +func (*UnimplementedQueryServer) GenesisTime(ctx context.Context, req *QueryGenesisTimeRequest) (*QueryGenesisTimeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GenesisTime not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_InflationRate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryInflationRateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).InflationRate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/celestia.mint.v1.Query/InflationRate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).InflationRate(ctx, req.(*QueryInflationRateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AnnualProvisions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAnnualProvisionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AnnualProvisions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/celestia.mint.v1.Query/AnnualProvisions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AnnualProvisions(ctx, req.(*QueryAnnualProvisionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GenesisTime_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGenesisTimeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GenesisTime(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/celestia.mint.v1.Query/GenesisTime", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GenesisTime(ctx, req.(*QueryGenesisTimeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "celestia.mint.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "InflationRate", + Handler: _Query_InflationRate_Handler, + }, + { + MethodName: "AnnualProvisions", + Handler: _Query_AnnualProvisions_Handler, + }, + { + MethodName: "GenesisTime", + Handler: _Query_GenesisTime_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "celestia/mint/v1/query.proto", +} + +func (m *QueryInflationRateRequest) 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 *QueryInflationRateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryInflationRateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryInflationRateResponse) 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 *QueryInflationRateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryInflationRateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.InflationRate.Size() + i -= size + if _, err := m.InflationRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAnnualProvisionsRequest) 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 *QueryAnnualProvisionsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAnnualProvisionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryAnnualProvisionsResponse) 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 *QueryAnnualProvisionsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAnnualProvisionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.AnnualProvisions.Size() + i -= size + if _, err := m.AnnualProvisions.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryGenesisTimeRequest) 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 *QueryGenesisTimeRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGenesisTimeRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryGenesisTimeResponse) 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 *QueryGenesisTimeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGenesisTimeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.GenesisTime != nil { + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.GenesisTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.GenesisTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintQuery(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryInflationRateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryInflationRateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.InflationRate.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAnnualProvisionsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryAnnualProvisionsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.AnnualProvisions.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryGenesisTimeRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryGenesisTimeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GenesisTime != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.GenesisTime) + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryInflationRateRequest) 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: QueryInflationRateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryInflationRateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryInflationRateResponse) 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: QueryInflationRateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryInflationRateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InflationRate", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InflationRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAnnualProvisionsRequest) 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: QueryAnnualProvisionsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAnnualProvisionsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryAnnualProvisionsResponse) 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: QueryAnnualProvisionsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAnnualProvisionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AnnualProvisions", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AnnualProvisions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGenesisTimeRequest) 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: QueryGenesisTimeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGenesisTimeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryGenesisTimeResponse) 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: QueryGenesisTimeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGenesisTimeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisTime", 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.GenesisTime == nil { + m.GenesisTime = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.GenesisTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/mint/types/query.pb.gw.go b/x/mint/types/query.pb.gw.go new file mode 100644 index 0000000..a3f1d4a --- /dev/null +++ b/x/mint/types/query.pb.gw.go @@ -0,0 +1,283 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: celestia/mint/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_InflationRate_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryInflationRateRequest + var metadata runtime.ServerMetadata + + msg, err := client.InflationRate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_InflationRate_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryInflationRateRequest + var metadata runtime.ServerMetadata + + msg, err := server.InflationRate(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AnnualProvisions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAnnualProvisionsRequest + var metadata runtime.ServerMetadata + + msg, err := client.AnnualProvisions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AnnualProvisions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAnnualProvisionsRequest + var metadata runtime.ServerMetadata + + msg, err := server.AnnualProvisions(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GenesisTime_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGenesisTimeRequest + var metadata runtime.ServerMetadata + + msg, err := client.GenesisTime(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GenesisTime_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGenesisTimeRequest + var metadata runtime.ServerMetadata + + msg, err := server.GenesisTime(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. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_InflationRate_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_InflationRate_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_InflationRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AnnualProvisions_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_AnnualProvisions_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_AnnualProvisions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GenesisTime_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_GenesisTime_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_GenesisTime_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_InflationRate_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_InflationRate_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_InflationRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AnnualProvisions_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_AnnualProvisions_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_AnnualProvisions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GenesisTime_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_GenesisTime_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_GenesisTime_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_InflationRate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "mint", "v1beta1", "inflation_rate"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AnnualProvisions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "mint", "v1beta1", "annual_provisions"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_GenesisTime_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "mint", "v1beta1", "genesis_time"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_InflationRate_0 = runtime.ForwardResponseMessage + + forward_Query_AnnualProvisions_0 = runtime.ForwardResponseMessage + + forward_Query_GenesisTime_0 = runtime.ForwardResponseMessage +)