diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f791ac1..3cbf80d56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Unreleased +### State Machine Breaking + +* [#211](https://github.com/babylonlabs-io/babylon/pull/211) Babylon inflation module + ### Improvements * [#235](https://github.com/babylonlabs-io/babylon/pull/235) Change default values diff --git a/app/app.go b/app/app.go index e22ac0155..fdf08a3d7 100644 --- a/app/app.go +++ b/app/app.go @@ -23,6 +23,8 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/babylonlabs-io/babylon/x/mint" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" abci "github.com/cometbft/cometbft/abci/types" cmtos "github.com/cometbft/cometbft/libs/os" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -67,8 +69,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" - "github.com/cosmos/cosmos-sdk/x/mint" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -285,7 +285,7 @@ func NewBabylonApp( crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index a35714006..a702c15a4 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -16,6 +16,8 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + mintkeeper "github.com/babylonlabs-io/babylon/x/mint/keeper" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" @@ -35,8 +37,6 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - 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" diff --git a/app/test_helpers.go b/app/test_helpers.go index 54514d809..c66b7b0e3 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -10,6 +10,7 @@ import ( "cosmossdk.io/log" "cosmossdk.io/math" pruningtypes "cosmossdk.io/store/pruning/types" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" tmjson "github.com/cometbft/cometbft/libs/json" @@ -27,7 +28,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/mempool" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" diff --git a/app/upgrades/v1/upgrades.go b/app/upgrades/v1/upgrades.go index 77f0d49eb..688273b15 100644 --- a/app/upgrades/v1/upgrades.go +++ b/app/upgrades/v1/upgrades.go @@ -19,7 +19,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + accountkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/babylonlabs-io/babylon/app/keepers" appparams "github.com/babylonlabs-io/babylon/app/params" @@ -31,6 +33,8 @@ import ( btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" finalitykeeper "github.com/babylonlabs-io/babylon/x/finality/keeper" finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" + mintkeeper "github.com/babylonlabs-io/babylon/x/mint/keeper" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" ) const ( @@ -60,16 +64,42 @@ func CreateUpgradeHandler(upgradeDataStr UpgradeDataString) upgrades.UpgradeHand return nil, err } + // Re-initialise the mint module as we have replaced Cosmos SDK's + // mint module with our own one. + err = upgradeMint( + ctx, + keepers.EncCfg.Codec, + &keepers.MintKeeper, + &keepers.AccountKeeper, + keepers.StakingKeeper, + ) + if err != nil { + return nil, err + } + err = upgradeParameters( - ctx, keepers.EncCfg.Codec, - &keepers.BTCStakingKeeper, &keepers.FinalityKeeper, &keepers.WasmKeeper, - upgradeDataStr.BtcStakingParamStr, upgradeDataStr.FinalityParamStr, upgradeDataStr.CosmWasmParamStr, + ctx, + keepers.EncCfg.Codec, + &keepers.BTCStakingKeeper, + &keepers.FinalityKeeper, + &keepers.WasmKeeper, + upgradeDataStr.BtcStakingParamStr, + upgradeDataStr.FinalityParamStr, + upgradeDataStr.CosmWasmParamStr, ) if err != nil { return nil, err } - if err := upgradeLaunch(ctx, keepers.EncCfg, &keepers.BTCLightClientKeeper, keepers.BankKeeper, upgradeDataStr.NewBtcHeadersStr, upgradeDataStr.TokensDistributionStr); err != nil { + err = upgradeLaunch( + ctx, + keepers.EncCfg, + &keepers.BTCLightClientKeeper, + keepers.BankKeeper, + upgradeDataStr.NewBtcHeadersStr, + upgradeDataStr.TokensDistributionStr, + ) + if err != nil { return nil, err } @@ -78,6 +108,23 @@ func CreateUpgradeHandler(upgradeDataStr UpgradeDataString) upgrades.UpgradeHand } } +func upgradeMint( + ctx sdk.Context, + cdc codec.Codec, + k *mintkeeper.Keeper, + ak *accountkeeper.AccountKeeper, + stk *stakingkeeper.Keeper, +) error { + bondedDenom, err := stk.BondDenom(ctx) + if err != nil { + return err + } + k.InitGenesis(ctx, ak, &minttypes.GenesisState{ + BondDenom: bondedDenom, + }) + return nil +} + func upgradeParameters( ctx sdk.Context, cdc codec.Codec, diff --git a/app/upgrades/v1/upgrades_test.go b/app/upgrades/v1/upgrades_test.go index e812c6c14..49a96ebf2 100644 --- a/app/upgrades/v1/upgrades_test.go +++ b/app/upgrades/v1/upgrades_test.go @@ -20,12 +20,12 @@ import ( "github.com/babylonlabs-io/babylon/app/upgrades" "github.com/babylonlabs-io/babylon/test/e2e/util" "github.com/babylonlabs-io/babylon/testutil/datagen" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/stretchr/testify/suite" "github.com/babylonlabs-io/babylon/app" diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index b099c2e09..6a992a54c 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -7,6 +7,8 @@ import ( "time" sdkmath "cosmossdk.io/math" + + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" comettypes "github.com/cometbft/cometbft/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -22,7 +24,6 @@ import ( genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctypes "github.com/cosmos/ibc-go/v8/modules/core/types" @@ -200,7 +201,7 @@ func PrepareGenesis( // mint module genesis mintGenState := minttypes.DefaultGenesisState() - mintGenState.Params = genesisParams.MintParams + mintGenState.BondDenom = genesisParams.StakingParams.BondDenom genesisState[minttypes.ModuleName] = cdc.MustMarshalJSON(mintGenState) // distribution module genesis @@ -250,7 +251,6 @@ type GenesisParams struct { NativeCoinMetadatas []banktypes.Metadata StakingParams stakingtypes.Params - MintParams minttypes.Params DistributionParams distributiontypes.Params GovParams govv1.Params @@ -337,15 +337,6 @@ func TestnetGenesisParams( genParams.StakingParams.MaxValidators = maxActiveValidators genParams.StakingParams.BondDenom = genParams.NativeCoinMetadatas[0].Base - genParams.MintParams = minttypes.DefaultParams() - genParams.MintParams.MintDenom = genParams.NativeCoinMetadatas[0].Base - genParams.MintParams.BlocksPerYear = blocksPerYear - // This should always work as inflation rate is already a float64 - genParams.MintParams.InflationRateChange = sdkmath.LegacyMustNewDecFromStr(fmt.Sprintf("%f", inflationRateChange)) - genParams.MintParams.InflationMin = sdkmath.LegacyMustNewDecFromStr(fmt.Sprintf("%f", inflationMin)) - genParams.MintParams.InflationMax = sdkmath.LegacyMustNewDecFromStr(fmt.Sprintf("%f", inflationMax)) - genParams.MintParams.GoalBonded = sdkmath.LegacyMustNewDecFromStr(fmt.Sprintf("%f", goalBonded)) - genParams.GovParams = govv1.DefaultParams() genParams.GovParams.MinDeposit = sdk.NewCoins(sdk.NewCoin( genParams.NativeCoinMetadatas[0].Base, diff --git a/proto/babylon/mint/v1/genesis.proto b/proto/babylon/mint/v1/genesis.proto new file mode 100644 index 000000000..defc3a588 --- /dev/null +++ b/proto/babylon/mint/v1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package babylon.mint.v1; + +option go_package = "github.com/babylonlabs-io/babylon/x/mint/types"; + +// GenesisState defines the mint module's genesis state. +message GenesisState { + reserved 1; // 1 was previously used for the `Minter` field. + + // BondDenom is the denomination of the token that should be minted. + string bond_denom = 2; +} diff --git a/proto/babylon/mint/v1/mint.proto b/proto/babylon/mint/v1/mint.proto new file mode 100644 index 000000000..b14f6efd0 --- /dev/null +++ b/proto/babylon/mint/v1/mint.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package babylon.mint.v1; + +option go_package = "github.com/babylonlabs-io/babylon/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) = "cosmossdk.io/math.LegacyDec", + (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) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; + + // 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; +} + +// GenesisTime contains the timestamp of the genesis block. +message GenesisTime { + // GenesisTime is the timestamp of the genesis block. + google.protobuf.Timestamp genesis_time = 1 [ (gogoproto.stdtime) = true ]; +} diff --git a/proto/babylon/mint/v1/query.proto b/proto/babylon/mint/v1/query.proto new file mode 100644 index 000000000..5d88e85d6 --- /dev/null +++ b/proto/babylon/mint/v1/query.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; +package babylon.mint.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "babylon/mint/v1/mint.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/babylonlabs-io/babylon/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) = "cosmossdk.io/math.LegacyDec", + (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) = "cosmossdk.io/math.LegacyDec", + (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/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index bc181dac4..2bcba9c63 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -8,6 +8,7 @@ import ( sdkmath "cosmossdk.io/math" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/server" @@ -19,7 +20,6 @@ import ( genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" staketypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" @@ -316,7 +316,7 @@ func updateGovGenesis(votingPeriod, expeditedVotingPeriod time.Duration) func(go } func updateMintGenesis(mintGenState *minttypes.GenesisState) { - mintGenState.Params.MintDenom = BabylonDenom + mintGenState.BondDenom = BabylonDenom } func updateStakeGenesis(stakeGenState *staketypes.GenesisState) { diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index 26a1ed76a..a61ca4a7a 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -11,12 +11,12 @@ import ( "cosmossdk.io/math" "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" "github.com/cometbft/cometbft/crypto" "github.com/cometbft/cometbft/crypto/ed25519" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/stretchr/testify/require" "github.com/babylonlabs-io/babylon/app" diff --git a/x/mint/README.md b/x/mint/README.md new file mode 100644 index 000000000..7fbf86428 --- /dev/null +++ b/x/mint/README.md @@ -0,0 +1,153 @@ +# `x/mint` + +- [Abstract](#abstract) + - [Inflation Schedule](#inflation-schedule) +- [Terms](#terms) +- [State](#state) +- [State Transitions](#state-transitions) + - [Begin Block](#begin-block) + - [Events](#events) +- [Client](#client) + - [CLI](#cli) +- [Genesis State](#genesis-state) +- [Params](#params) +- [Assumptions and Considerations](#assumptions-and-considerations) +- [Implementation](#implementation) +- [References](#references) + +## Abstract + +Babylon's `x/mint` is a fork of the Cosmos SDK +[`x/mint`](https://github.com/cosmos/cosmos-sdk/tree/main/x/mint) module that +makes some changes to the inflation mechanism. The code is adapted from +[Celestia's mint +module](https://github.com/celestiaorg/celestia-app/tree/main/x/mint). + +### 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 | + +- **Year** indicates the number of years elapsed since chain genesis. +- **Inflation (%)** indicates the percentage of the total supply that will be + minted in the next year. + +## Terms + +- **Inflation Rate**: The percentage of the total supply that will be minted + each year. The inflation rate is calculated once per year on the anniversary + of chain genesis based on the number of years elapsed since genesis. The + inflation rate is calculated as `InitialInflationRate * ((1 - + DisinflationRate) ^ YearsSinceGenesis)`. See + [./types/constants.go](./types/constants.go) for the constants used in this + module. +- **Annual Provisions**: The total amount of tokens that will be minted each + year. Annual provisions are calculated once per year on the anniversary of + chain genesis based on the total supply and the inflation rate. Annual + provisions are calculated as `TotalSupply * InflationRate` +- **Block Provision**: The amount of tokens that will be minted in the current + block. Block provisions are calculated once per block based on the annual + provisions and the number of nanoseconds elapsed between the current block and + the previous block. Block provisions are calculated as `AnnualProvisions * + (NanosecondsSincePreviousBlock / NanosecondsPerYear)` + +## State + +See [./types/minter.go](./types/minter.go) for the `Minter` struct which +contains this module's state. + +## State Transitions + +The `Minter` struct is updated every block via `BeginBlocker`. + +### Begin Block + +See `BeginBlocker` in [./abci.go](./abci.go). + +### Events + +An event is emitted every block when a block provision is minted. See +`mintBlockProvision` in [./abci.go](./abci.go). + +## Client + +### CLI + +```shell +$ babylond query mint annual-provisions +80235005639941.760000000000000000 +``` + +```shell +$ babylond query mint genesis-time +2023-05-09 00:56:15.59304 +0000 UTC +``` + +```shell +$ babylond query mint inflation +0.080000000000000000 +``` + +## Genesis State + +The genesis state is defined in [./types/genesis.go](./types/genesis.go). + +## Params + +All params have been removed from this module because they should not be +modifiable via governance. The constants used in this module are defined in +[./types/constants.go](./types/constants.go) and they are subject to change via +hardforks. + +## Assumptions and Considerations + +> For the Gregorian calendar, the average length of the calendar year (the mean +> year) across the complete leap cycle of 400 years is 365.2425 days (97 out of +> 400 years are leap years). + +Source: + +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 := time.Duration(minttypes.NanosecondsPerYear) + +// oneYear is 31,536,000 seconds which will likely return unexpected results in tests +oneYear := time.Hour * 24 * 365 +``` + +## Implementation + +See [x/mint](../../x/mint) for the implementation of this module. + +## References + +1. [ADR-031](https://github.com/babylonlabs-io/pm/blob/main/adr/adr-031-mint-module.md) +2. [Celestia's + ADR-019](https://github.com/celestiaorg/celestia-app/tree/main/docs/architecture/adr-019-strict-inflation-schedule.md) +3. [Celestia's mint + module](https://github.com/celestiaorg/celestia-app/tree/main/x/mint) diff --git a/x/mint/abci.go b/x/mint/abci.go new file mode 100644 index 000000000..dcb7257e1 --- /dev/null +++ b/x/mint/abci.go @@ -0,0 +1,103 @@ +package mint + +import ( + "context" + "time" + + "github.com/babylonlabs-io/babylon/x/mint/keeper" + "github.com/babylonlabs-io/babylon/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 context.Context, k keeper.Keeper) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + maybeUpdateMinter(ctx, k) + mintBlockProvision(ctx, k) + setPreviousBlockTime(ctx, k) +} + +// maybeUpdateMinter updates the inflation rate and annual provisions if the +// inflation rate has changed. The inflation rate is expected to change once per +// year at the genesis time anniversary until the TargetInflationRate is +// reached. +func maybeUpdateMinter(ctx context.Context, k keeper.Keeper) { + minter := k.GetMinter(ctx) + genesisTime := k.GetGenesisTime(ctx).GenesisTime + sdkCtx := sdk.UnwrapSDKContext(ctx) + newInflationRate := minter.CalculateInflationRate(sdkCtx, *genesisTime) + + isNonZeroAnnualProvisions := !minter.AnnualProvisions.IsZero() + if newInflationRate.Equal(minter.InflationRate) && isNonZeroAnnualProvisions { + // The minter's InflationRate and AnnualProvisions already reflect the + // values for this year. Exit early because we don't need to update + // them. AnnualProvisions must be updated if it is zero (expected at + // genesis). + return + } + + totalSupply, err := k.StakingTokenSupply(ctx) + if err != nil { + panic(err) + } + + minter.InflationRate = newInflationRate + minter.AnnualProvisions = newInflationRate.MulInt(totalSupply) + if err := k.SetMinter(ctx, minter); err != nil { + panic(err) + } +} + +// mintBlockProvision mints the block provision for the current block. +func mintBlockProvision(ctx context.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 + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + + toMintCoin, err := minter.CalculateBlockProvision(sdkCtx.BlockTime(), *minter.PreviousBlockTime) + if err != nil { + panic(err) + } + 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") + } + + sdkCtx.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 context.Context, k keeper.Keeper) { + minter := k.GetMinter(ctx) + sdkCtx := sdk.UnwrapSDKContext(ctx) + blockTime := sdkCtx.BlockTime() + minter.PreviousBlockTime = &blockTime + if err := k.SetMinter(ctx, minter); err != nil { + panic(err) + } +} diff --git a/x/mint/abci_test.go b/x/mint/abci_test.go new file mode 100644 index 000000000..e50be7b6b --- /dev/null +++ b/x/mint/abci_test.go @@ -0,0 +1,134 @@ +package mint_test + +import ( + "fmt" + "testing" + "time" + + "cosmossdk.io/log" + "cosmossdk.io/math" + "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/mint" + minttypes "github.com/babylonlabs-io/babylon/x/mint/types" + "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var oneYear = time.Duration(minttypes.NanosecondsPerYear) + +func TestInflationRate(t *testing.T) { + h := helper.NewHelper(t) + app := h.App + ctx := sdk.NewContext(app.CommitMultiStore(), types.Header{}, false, log.NewNopLogger()) + genesisTime := app.MintKeeper.GetGenesisTime(ctx).GenesisTime + + yearOneMinusOneSecond := genesisTime.Add(oneYear).Add(-time.Second) + yearOne := genesisTime.Add(oneYear) + yearTwo := genesisTime.Add(2 * oneYear) + yearFifteen := genesisTime.Add(15 * oneYear) + yearTwenty := genesisTime.Add(20 * oneYear) + + type testCase struct { + name string + ctx sdk.Context + want math.LegacyDec + } + + testCases := []testCase{ + { + name: "inflation rate is 0.08 for year zero", + ctx: ctx.WithBlockHeight(1).WithBlockTime(*genesisTime), + want: math.LegacyMustNewDecFromStr("0.08"), + }, + { + name: "inflation rate is 0.08 for year one minus one second", + ctx: ctx.WithBlockTime(yearOneMinusOneSecond), + want: math.LegacyMustNewDecFromStr("0.08"), + }, + { + name: "inflation rate is 0.072 for year one", + ctx: ctx.WithBlockTime(yearOne), + want: math.LegacyMustNewDecFromStr("0.072"), + }, + { + name: "inflation rate is 0.0648 for year two", + ctx: ctx.WithBlockTime(yearTwo), + want: math.LegacyMustNewDecFromStr("0.0648"), + }, + { + name: "inflation rate is 0.01647129056757192 for year fifteen", + ctx: ctx.WithBlockTime(yearFifteen), + want: math.LegacyMustNewDecFromStr("0.01647129056757192"), + }, + { + name: "inflation rate is 0.015 for year twenty", + ctx: ctx.WithBlockTime(yearTwenty), + want: math.LegacyMustNewDecFromStr("0.015"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + 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) { + t.Run("annual provisions are set after the chain starts", func(t *testing.T) { + h := helper.NewHelper(t) + a, ctx := h.App, h.Ctx + + assert.False(t, a.MintKeeper.GetMinter(ctx).AnnualProvisions.IsZero()) + }) + + t.Run("annual provisions are not updated more than once per year", func(t *testing.T) { + h := helper.NewHelper(t) + a, ctx := h.App, h.Ctx + + genesisTime := a.MintKeeper.GetGenesisTime(ctx).GenesisTime + yearOneMinusOneSecond := genesisTime.Add(oneYear).Add(-time.Second) + + initialSupply, err := a.StakingKeeper.StakingTokenSupply(ctx) + require.NoError(t, err) + stakingBondDenom, err := a.StakingKeeper.BondDenom(ctx) + require.NoError(t, err) + require.Equal(t, a.MintKeeper.GetMinter(ctx).BondDenom, stakingBondDenom) + + blockInterval := time.Second * 15 + + want := minttypes.InitialInflationRateAsDec().MulInt(initialSupply) + + type testCase struct { + height int64 + time time.Time + } + testCases := []testCase{ + {1, genesisTime.Add(blockInterval)}, + {2, genesisTime.Add(blockInterval * 2)}, + {3, yearOneMinusOneSecond}, + // testing annual provisions for years after year zero depends on the + // total supply which increased due to inflation in year zero. + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("block height %v", tc.height), func(t *testing.T) { + ctx = ctx.WithBlockHeight(tc.height).WithBlockTime(tc.time) + mint.BeginBlocker(ctx, a.MintKeeper) + assert.True(t, a.MintKeeper.GetMinter(ctx).AnnualProvisions.Equal(want)) + }) + } + + t.Run("one year later", func(t *testing.T) { + yearOne := genesisTime.Add(oneYear) + ctx = ctx.WithBlockHeight(5).WithBlockTime(yearOne) + mint.BeginBlocker(ctx, a.MintKeeper) + assert.False(t, a.MintKeeper.GetMinter(ctx).AnnualProvisions.Equal(want)) + }) + }) +} diff --git a/x/mint/client/cli/query.go b/x/mint/client/cli/query.go new file mode 100644 index 000000000..15f898f97 --- /dev/null +++ b/x/mint/client/cli/query.go @@ -0,0 +1,116 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/babylonlabs-io/babylon/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, _ []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, _ []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, _ []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/keeper/genesis.go b/x/mint/keeper/genesis.go new file mode 100644 index 000000000..afa0b5cc0 --- /dev/null +++ b/x/mint/keeper/genesis.go @@ -0,0 +1,33 @@ +package keeper + +import ( + "github.com/babylonlabs-io/babylon/x/mint/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis initializes the x/mint store with data from the genesis state. +func (k Keeper) InitGenesis(ctx sdk.Context, ak types.AccountKeeper, data *types.GenesisState) { + minter := types.DefaultMinter() + minter.BondDenom = data.BondDenom + if err := k.SetMinter(ctx, minter); err != nil { + panic(err) + } + // override the genesis time with the actual genesis time supplied in `InitChain` + blockTime := ctx.BlockTime() + gt := types.GenesisTime{ + GenesisTime: &blockTime, + } + if err := k.SetGenesisTime(ctx, gt); err != nil { + panic(err) + } + // Although ak.GetModuleAccount appears to be a no-op, it actually creates a + // new module account in the x/auth account store if it doesn't exist. See + // the x/auth keeper for more details. + ak.GetModuleAccount(ctx, types.ModuleName) +} + +// ExportGenesis returns a x/mint GenesisState for the given context. +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + bondDenom := k.GetMinter(ctx).BondDenom + return types.NewGenesisState(bondDenom) +} diff --git a/x/mint/keeper/grpc_query.go b/x/mint/keeper/grpc_query.go new file mode 100644 index 000000000..0779c5f63 --- /dev/null +++ b/x/mint/keeper/grpc_query.go @@ -0,0 +1,34 @@ +package keeper + +import ( + "context" + + "github.com/babylonlabs-io/babylon/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 the GensisTime of the mint module. +func (k Keeper) GenesisTime(c context.Context, _ *types.QueryGenesisTimeRequest) (*types.QueryGenesisTimeResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + genesisTime := k.GetGenesisTime(ctx).GenesisTime + + return &types.QueryGenesisTimeResponse{GenesisTime: 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 000000000..77d647941 --- /dev/null +++ b/x/mint/keeper/grpc_query_test.go @@ -0,0 +1,56 @@ +package keeper_test //nolint:all + +import ( + gocontext "context" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/mint/types" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type MintTestSuite struct { + suite.Suite + + app *app.BabylonApp + ctx sdk.Context + queryClient types.QueryClient +} + +func (suite *MintTestSuite) SetupTest() { + h := helper.NewHelper(suite.T()) + testApp, ctx := h.App, h.Ctx + + 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.GetGenesisTime(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 000000000..5de927f49 --- /dev/null +++ b/x/mint/keeper/keeper.go @@ -0,0 +1,121 @@ +package keeper + +import ( + "context" + "fmt" + + "cosmossdk.io/collections" + "cosmossdk.io/core/store" + "cosmossdk.io/log" + "cosmossdk.io/math" + + "github.com/babylonlabs-io/babylon/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Keeper of the mint store +type Keeper struct { + cdc codec.BinaryCodec + storeService store.KVStoreService + stakingKeeper types.StakingKeeper + bankKeeper types.BankKeeper + feeCollectorName string + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string + + Schema collections.Schema + MinterStore collections.Item[types.Minter] + GenesisTimeStore collections.Item[types.GenesisTime] +} + +// NewKeeper creates a new mint Keeper instance. +func NewKeeper( + cdc codec.BinaryCodec, + storeService store.KVStoreService, + stakingKeeper types.StakingKeeper, + ak types.AccountKeeper, + bankKeeper types.BankKeeper, + feeCollectorName string, + authority 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") + } + + sb := collections.NewSchemaBuilder(storeService) + k := Keeper{ + cdc: cdc, + storeService: storeService, + stakingKeeper: stakingKeeper, + bankKeeper: bankKeeper, + feeCollectorName: feeCollectorName, + authority: authority, + MinterStore: collections.NewItem(sb, types.MinterKey, "minter", codec.CollValue[types.Minter](cdc)), + GenesisTimeStore: collections.NewItem(sb, types.GenesisTimeKey, "genesis_time", codec.CollValue[types.GenesisTime](cdc)), + } + + schema, err := sb.Build() + if err != nil { + panic(err) + } + k.Schema = schema + + return k +} + +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetMinter returns the minter. +func (k Keeper) GetMinter(ctx context.Context) types.Minter { + minter, err := k.MinterStore.Get(ctx) + if err != nil { + panic(err) + } + return minter +} + +// SetMinter sets the minter. +func (k Keeper) SetMinter(ctx context.Context, minter types.Minter) error { + return k.MinterStore.Set(ctx, minter) +} + +// GetGenesisTime returns the genesis time. +func (k Keeper) GetGenesisTime(ctx context.Context) (gt types.GenesisTime) { + genesisTime, err := k.GenesisTimeStore.Get(ctx) + if err != nil { + panic(err) + } + return genesisTime +} + +// SetGenesisTime sets the genesis time. +func (k Keeper) SetGenesisTime(ctx context.Context, gt types.GenesisTime) error { + return k.GenesisTimeStore.Set(ctx, gt) +} + +// StakingTokenSupply implements an alias call to the underlying staking keeper's +// StakingTokenSupply. +func (k Keeper) StakingTokenSupply(ctx context.Context) (math.Int, error) { + return k.stakingKeeper.StakingTokenSupply(ctx) +} + +// MintCoins implements an alias call to the underlying bank keeper's +// MintCoins. +func (k Keeper) MintCoins(ctx context.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 context.Context, coins sdk.Coins) error { + return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.feeCollectorName, coins) +} diff --git a/x/mint/module.go b/x/mint/module.go new file mode 100644 index 000000000..d92c904f6 --- /dev/null +++ b/x/mint/module.go @@ -0,0 +1,165 @@ +package mint + +import ( + "context" + "encoding/json" + "fmt" + + "cosmossdk.io/core/appmodule" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "github.com/babylonlabs-io/babylon/x/mint/client/cli" + "github.com/babylonlabs-io/babylon/x/mint/keeper" + "github.com/babylonlabs-io/babylon/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{} + _ appmodule.HasBeginBlocker = AppModule{} +) + +// 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) {} + +// QuerierRoute returns the mint module's querier route name. +func (AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// 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 context.Context) error { + BeginBlocker(ctx, am.keeper) + return nil +} + +// 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.WeightedProposalMsg { + return nil +} + +// WeightedOperations doesn't return any mint module operation. +func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() { // marker +} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() { // marker +} diff --git a/x/mint/module_test.go b/x/mint/module_test.go new file mode 100644 index 000000000..2bb48a10c --- /dev/null +++ b/x/mint/module_test.go @@ -0,0 +1,18 @@ +package mint_test + +import ( + "testing" + + "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/mint/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" +) + +func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { + h := helper.NewHelper(t) + app, ctx := h.App, h.Ctx + + 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 000000000..1f0298b84 --- /dev/null +++ b/x/mint/simulation/decoder.go @@ -0,0 +1,31 @@ +package simulation + +import ( + "bytes" + "fmt" + + "github.com/babylonlabs-io/babylon/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.MinterKey): + var minterA, minterB types.Minter + cdc.MustUnmarshal(kvA.Value, &minterA) + cdc.MustUnmarshal(kvB.Value, &minterB) + return fmt.Sprintf("%v\n%v", minterA, minterB) + case bytes.Equal(kvA.Key, types.GenesisTimeKey): + var genesisTimeA, genesisTimeB types.GenesisTime + cdc.MustUnmarshal(kvA.Value, &genesisTimeA) + cdc.MustUnmarshal(kvB.Value, &genesisTimeB) + return fmt.Sprintf("%v\n%v", genesisTimeA, genesisTimeB) + 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 000000000..3f1fd073d --- /dev/null +++ b/x/mint/simulation/decoder_test.go @@ -0,0 +1,62 @@ +package simulation_test + +import ( + "fmt" + "testing" + "time" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/x/mint/simulation" + "github.com/babylonlabs-io/babylon/x/mint/types" + "github.com/cosmos/cosmos-sdk/types/kv" +) + +func TestDecodeStore(t *testing.T) { + cdc := appparams.DefaultEncodingConfig().Codec + decoder := simulation.NewDecodeStore(cdc) + minter := types.NewMinter(math.LegacyOneDec(), math.LegacyNewDec(15), appparams.DefaultBondDenom) + unixEpoch := time.Unix(0, 0).UTC() + genesisTime := types.GenesisTime{GenesisTime: &unixEpoch} + + kvPairs := kv.Pairs{ + Pairs: []kv.Pair{ + {Key: types.MinterKey, Value: cdc.MustMarshal(&minter)}, + {Key: types.GenesisTimeKey, Value: cdc.MustMarshal(&genesisTime)}, + {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: "GenesisTime", + expected: fmt.Sprintf("%v\n%v", genesisTime, genesisTime), + expectPanic: false, + }, + { + name: "other", + expected: "", + expectPanic: true, + }, + } + + for i, tt := range tests { + 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/constants.go b/x/mint/types/constants.go new file mode 100644 index 000000000..6da66546a --- /dev/null +++ b/x/mint/types/constants.go @@ -0,0 +1,46 @@ +package types + +import ( + "cosmossdk.io/math" +) + +// TODO: should these be parameters? +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 = int64(SecondsPerMinute * MinutesPerHour * HoursPerDay * DaysPerYear) // 31,556,952 + NanosecondsPerYear = NanosecondsPerSecond * SecondsPerYear // 31,556,952,000,000,000 + + // InitialInflationRate is the inflation rate that the network starts at. + InitialInflationRate = 0.08 + // DisinflationRate is the rate at which the inflation rate decreases each year. + DisinflationRate = 0.1 + // TargetInflationRate is the inflation rate that the network aims to + // stabilize at. In practice, TargetInflationRate acts as a minimum so that + // the inflation rate doesn't decrease after reaching it. + TargetInflationRate = 0.015 +) + +var ( + initialInflationRateAsDec = math.LegacyNewDecWithPrec(InitialInflationRate*1000, 3) + disinflationRateAsDec = math.LegacyNewDecWithPrec(DisinflationRate*1000, 3) + targetInflationRateAsDec = math.LegacyNewDecWithPrec(TargetInflationRate*1000, 3) +) + +func InitialInflationRateAsDec() math.LegacyDec { + return initialInflationRateAsDec +} + +func DisinflationRateAsDec() math.LegacyDec { + return disinflationRateAsDec +} + +func TargetInflationRateAsDec() math.LegacyDec { + return targetInflationRateAsDec +} diff --git a/x/mint/types/events.go b/x/mint/types/events.go new file mode 100644 index 000000000..9dea531eb --- /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 000000000..5c4409581 --- /dev/null +++ b/x/mint/types/expected_keepers.go @@ -0,0 +1,26 @@ +package types + +import ( + context "context" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// StakingKeeper defines the expected staking keeper. +type StakingKeeper interface { + StakingTokenSupply(ctx context.Context) (math.Int, error) +} + +// AccountKeeper defines the contract required for account APIs. +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetModuleAccount(ctx context.Context, name string) sdk.ModuleAccountI +} + +// BankKeeper defines the contract needed to be fulfilled for banking and supply +// dependencies. +type BankKeeper interface { + SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error + MintCoins(ctx context.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 000000000..9fec24f16 --- /dev/null +++ b/x/mint/types/genesis.go @@ -0,0 +1,26 @@ +package types + +import "errors" + +// NewGenesisState creates a new GenesisState object +func NewGenesisState(bondDenom string) *GenesisState { + return &GenesisState{ + BondDenom: bondDenom, + } +} + +// DefaultGenesisState creates a default GenesisState object +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + BondDenom: DefaultBondDenom, + } +} + +// ValidateGenesis validates the provided genesis state to ensure the +// expected invariants holds. +func ValidateGenesis(data GenesisState) error { + if data.BondDenom == "" { + return errors.New("bond denom cannot be empty") + } + return nil +} diff --git a/x/mint/types/genesis.pb.go b/x/mint/types/genesis.pb.go new file mode 100644 index 000000000..8880ee04d --- /dev/null +++ b/x/mint/types/genesis.pb.go @@ -0,0 +1,317 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: babylon/mint/v1/genesis.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/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 { + // BondDenom is the denomination of the token that should be minted. + BondDenom string `protobuf:"bytes,2,opt,name=bond_denom,json=bondDenom,proto3" json:"bond_denom,omitempty"` +} + +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_cc1262885e03592c, []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) GetBondDenom() string { + if m != nil { + return m.BondDenom + } + return "" +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "babylon.mint.v1.GenesisState") +} + +func init() { proto.RegisterFile("babylon/mint/v1/genesis.proto", fileDescriptor_cc1262885e03592c) } + +var fileDescriptor_cc1262885e03592c = []byte{ + // 175 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4d, 0x4a, 0x4c, 0xaa, + 0xcc, 0xc9, 0xcf, 0xd3, 0xcf, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, + 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x87, 0x4a, 0xeb, 0x81, 0xa4, + 0xf5, 0xca, 0x0c, 0x95, 0x8c, 0xb9, 0x78, 0xdc, 0x21, 0x2a, 0x82, 0x4b, 0x12, 0x4b, 0x52, 0x85, + 0x64, 0xb9, 0xb8, 0x92, 0xf2, 0xf3, 0x52, 0xe2, 0x53, 0x52, 0xf3, 0xf2, 0x73, 0x25, 0x98, 0x14, + 0x18, 0x35, 0x38, 0x83, 0x38, 0x41, 0x22, 0x2e, 0x20, 0x01, 0x2f, 0x16, 0x0e, 0x46, 0x01, 0x26, + 0x27, 0x8f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, + 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xd2, 0x4b, 0xcf, 0x2c, + 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x5a, 0x95, 0x93, 0x98, 0x54, 0xac, 0x9b, + 0x99, 0x0f, 0xe3, 0xea, 0x57, 0x40, 0x9c, 0x56, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, + 0x96, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xb8, 0x8a, 0x90, 0xb7, 0x00, 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 + if len(m.BondDenom) > 0 { + i -= len(m.BondDenom) + copy(dAtA[i:], m.BondDenom) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.BondDenom))) + i-- + dAtA[i] = 0x12 + } + 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 = len(m.BondDenom) + if l > 0 { + 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 2: + 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 ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BondDenom = string(dAtA[iNdEx:postIndex]) + 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 000000000..9a8a5ff44 --- /dev/null +++ b/x/mint/types/keys.go @@ -0,0 +1,26 @@ +package types + +import "cosmossdk.io/collections" + +var ( + MinterKey = collections.NewPrefix(0) + //nolint:unused + reservedKey = collections.NewPrefix(1) // reserved for parameters + GenesisTimeKey = collections.NewPrefix(2) +) + +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 000000000..1ca04a527 --- /dev/null +++ b/x/mint/types/mint.pb.go @@ -0,0 +1,675 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: babylon/mint/v1/mint.proto + +package types + +import ( + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/protobuf/types/known/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 cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=inflation_rate,json=inflationRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"inflation_rate"` + // AnnualProvisions is the total number of tokens to be minted in the current + // year due to inflation. + AnnualProvisions cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=annual_provisions,json=annualProvisions,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"annual_provisions"` + // 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_a78f7d85d8f9d75c, []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) GetPreviousBlockTime() *time.Time { + if m != nil { + return m.PreviousBlockTime + } + return nil +} + +func (m *Minter) GetBondDenom() string { + if m != nil { + return m.BondDenom + } + return "" +} + +// GenesisTime contains the timestamp of the genesis block. +type GenesisTime struct { + // GenesisTime is the timestamp of the genesis block. + GenesisTime *time.Time `protobuf:"bytes,1,opt,name=genesis_time,json=genesisTime,proto3,stdtime" json:"genesis_time,omitempty"` +} + +func (m *GenesisTime) Reset() { *m = GenesisTime{} } +func (m *GenesisTime) String() string { return proto.CompactTextString(m) } +func (*GenesisTime) ProtoMessage() {} +func (*GenesisTime) Descriptor() ([]byte, []int) { + return fileDescriptor_a78f7d85d8f9d75c, []int{1} +} +func (m *GenesisTime) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisTime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisTime.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 *GenesisTime) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisTime.Merge(m, src) +} +func (m *GenesisTime) XXX_Size() int { + return m.Size() +} +func (m *GenesisTime) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisTime.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisTime proto.InternalMessageInfo + +func (m *GenesisTime) GetGenesisTime() *time.Time { + if m != nil { + return m.GenesisTime + } + return nil +} + +func init() { + proto.RegisterType((*Minter)(nil), "babylon.mint.v1.Minter") + proto.RegisterType((*GenesisTime)(nil), "babylon.mint.v1.GenesisTime") +} + +func init() { proto.RegisterFile("babylon/mint/v1/mint.proto", fileDescriptor_a78f7d85d8f9d75c) } + +var fileDescriptor_a78f7d85d8f9d75c = []byte{ + // 386 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0xcd, 0x6e, 0xd4, 0x30, + 0x10, 0x8e, 0xab, 0x52, 0xa9, 0x5e, 0xfe, 0x1a, 0x38, 0x84, 0x20, 0x92, 0xaa, 0xa7, 0x5e, 0x6a, + 0x6b, 0xe1, 0x0d, 0xc2, 0x4a, 0x70, 0x00, 0xa9, 0x8a, 0x38, 0x20, 0x0e, 0x44, 0x76, 0xd6, 0x75, + 0xad, 0x26, 0x9e, 0x28, 0x76, 0x22, 0xf6, 0x2d, 0xfa, 0x2e, 0xf0, 0x10, 0x3d, 0xae, 0x38, 0x21, + 0x0e, 0x0b, 0xda, 0x7d, 0x11, 0xe4, 0x38, 0x59, 0xae, 0x88, 0x53, 0xf2, 0xcd, 0x37, 0xf3, 0x7d, + 0xe3, 0x4f, 0x83, 0x63, 0xce, 0xf8, 0xaa, 0x02, 0x4d, 0x6b, 0xa5, 0x2d, 0xed, 0xe7, 0xc3, 0x97, + 0x34, 0x2d, 0x58, 0x08, 0x1f, 0x8d, 0x1c, 0x19, 0x6a, 0xfd, 0x3c, 0x7e, 0x2a, 0x41, 0xc2, 0xc0, + 0x51, 0xf7, 0xe7, 0xdb, 0xe2, 0x67, 0x25, 0x98, 0x1a, 0x4c, 0xe1, 0x09, 0x0f, 0x46, 0x2a, 0x95, + 0x00, 0xb2, 0x12, 0x74, 0x40, 0xbc, 0xbb, 0xa2, 0x56, 0xd5, 0xc2, 0x58, 0x56, 0x37, 0xbe, 0xe1, + 0xec, 0xeb, 0x01, 0x3e, 0x7a, 0xaf, 0xb4, 0x15, 0x6d, 0xf8, 0x11, 0x3f, 0x54, 0xfa, 0xaa, 0x62, + 0x56, 0x81, 0x2e, 0x5a, 0x66, 0x45, 0x84, 0x4e, 0xd1, 0xf9, 0x71, 0x36, 0xbf, 0xdb, 0xa4, 0xc1, + 0xcf, 0x4d, 0xfa, 0xdc, 0x2b, 0x9b, 0xe5, 0x0d, 0x51, 0x40, 0x6b, 0x66, 0xaf, 0xc9, 0x3b, 0x21, + 0x59, 0xb9, 0x5a, 0x88, 0xf2, 0xfb, 0xb7, 0x0b, 0x3c, 0x1a, 0x2f, 0x44, 0x99, 0x3f, 0xd8, 0x0b, + 0xe5, 0xcc, 0x8a, 0xf0, 0x33, 0x3e, 0x61, 0x5a, 0x77, 0xac, 0x72, 0x2b, 0xf6, 0xca, 0x28, 0xd0, + 0x26, 0x3a, 0xf8, 0x5f, 0xf1, 0xc7, 0x5e, 0xeb, 0x72, 0x2f, 0x15, 0x5e, 0xe2, 0x27, 0x4d, 0x2b, + 0x7a, 0x05, 0x9d, 0x29, 0x78, 0x05, 0xe5, 0x4d, 0xe1, 0x9e, 0x19, 0x1d, 0x9e, 0xa2, 0xf3, 0xd9, + 0xcb, 0x98, 0xf8, 0x0c, 0xc8, 0x94, 0x01, 0xf9, 0x30, 0x65, 0x90, 0x1d, 0xde, 0xfe, 0x4a, 0x51, + 0x7e, 0x32, 0x0d, 0x67, 0x6e, 0xd6, 0xb1, 0xe1, 0x0b, 0x8c, 0x39, 0xe8, 0x65, 0xb1, 0x14, 0x1a, + 0xea, 0xe8, 0x9e, 0x5b, 0x35, 0x3f, 0x76, 0x95, 0x85, 0x2b, 0x9c, 0xe5, 0x78, 0xf6, 0x46, 0x68, + 0x61, 0x94, 0x19, 0xba, 0x5f, 0xe3, 0xfb, 0xd2, 0x43, 0x6f, 0x8c, 0xfe, 0xd1, 0x78, 0x26, 0xff, + 0x8a, 0x64, 0x6f, 0xef, 0xb6, 0x09, 0x5a, 0x6f, 0x13, 0xf4, 0x7b, 0x9b, 0xa0, 0xdb, 0x5d, 0x12, + 0xac, 0x77, 0x49, 0xf0, 0x63, 0x97, 0x04, 0x9f, 0x88, 0x54, 0xf6, 0xba, 0xe3, 0xa4, 0x84, 0x9a, + 0x8e, 0x17, 0x51, 0x31, 0x6e, 0x2e, 0x14, 0x4c, 0x90, 0x7e, 0xf1, 0xe7, 0x63, 0x57, 0x8d, 0x30, + 0xfc, 0x68, 0x30, 0x7c, 0xf5, 0x27, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x0d, 0x96, 0x13, 0x5b, 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_cosmos_gogoproto_types.StdTimeMarshalTo(*m.PreviousBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.PreviousBlockTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintMint(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x22 + } + { + 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 (m *GenesisTime) 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 *GenesisTime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisTime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.GenesisTime != nil { + n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.GenesisTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.GenesisTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintMint(dAtA, i, uint64(n2)) + 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.PreviousBlockTime != nil { + l = github_com_cosmos_gogoproto_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 (m *GenesisTime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GenesisTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.GenesisTime) + 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 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_cosmos_gogoproto_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 (m *GenesisTime) 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: GenesisTime: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisTime: 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 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_cosmos_gogoproto_types.StdTimeUnmarshal(m.GenesisTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 000000000..7c0ee60dd --- /dev/null +++ b/x/mint/types/minter.go @@ -0,0 +1,74 @@ +package types + +import ( + "fmt" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const DefaultBondDenom = "ubbn" + +// NewMinter returns a new Minter object. +func NewMinter(inflationRate math.LegacyDec, annualProvisions math.LegacyDec, bondDenom string) Minter { + return Minter{ + InflationRate: inflationRate, + AnnualProvisions: annualProvisions, + BondDenom: bondDenom, + } +} + +// DefaultMinter returns a Minter object with default values. +func DefaultMinter() Minter { + annualProvisions := math.LegacyNewDec(0) + return NewMinter(InitialInflationRateAsDec(), annualProvisions, 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, genesis time.Time) math.LegacyDec { + years := yearsSinceGenesis(genesis, ctx.BlockTime()) + inflationRate := InitialInflationRateAsDec().Mul(math.LegacyOneDec().Sub(DisinflationRateAsDec()).Power(uint64(years))) + + if inflationRate.LT(TargetInflationRateAsDec()) { + return TargetInflationRateAsDec() + } + return inflationRate +} + +// 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, error) { + if current.Before(previous) { + return sdk.Coin{}, fmt.Errorf("current time %v cannot be before previous time %v", current, previous) + } + timeElapsed := current.Sub(previous).Nanoseconds() + portionOfYear := math.LegacyNewDec(timeElapsed).Quo(math.LegacyNewDec(NanosecondsPerYear)) + blockProvision := m.AnnualProvisions.Mul(portionOfYear) + return sdk.NewCoin(m.BondDenom, blockProvision.TruncateInt()), nil +} + +// 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() / NanosecondsPerYear +} diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go new file mode 100644 index 000000000..a2a066912 --- /dev/null +++ b/x/mint/types/minter_test.go @@ -0,0 +1,261 @@ +package types + +import ( + "math/rand" + "testing" + time "time" + + "cosmossdk.io/math" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestCalculateInflationRate(t *testing.T) { + minter := DefaultMinter() + genesisTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) + + type testCase struct { + year int64 + 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 * int64(time.Nanosecond)) + blockTime := genesisTime.Add(years) + ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil).WithBlockTime(blockTime) + inflationRate := minter.CalculateInflationRate(ctx, genesisTime) + 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 := math.LegacyNewDec(1_000_000_000_000) // 1 trillion ubbn + annualProvisions := totalSupply.Mul(InitialInflationRateAsDec()) // 80 billion ubbn + + type testCase struct { + name string + annualProvisions math.LegacyDec + current time.Time + previous time.Time + want sdk.Coin + wantErr bool + } + + testCases := []testCase{ + { + name: "one 15 second block during the first year", + annualProvisions: annualProvisions, + current: current, + previous: current.Add(-blockInterval), + // 80 billion ubbn (annual provisions) * 15 (seconds) / 31,556,952 (seconds per year) = 38026.48620817 which truncates to 38026 ubbn + want: sdk.NewCoin(DefaultBondDenom, math.NewInt(38026)), + }, + { + name: "one 30 second block during the first year", + annualProvisions: annualProvisions, + current: current, + previous: current.Add(-2 * blockInterval), + // 80 billion ubbn (annual provisions) * 30 (seconds) / 31,556,952 (seconds per year) = 76052.97241635 which truncates to 76052 ubbn + want: sdk.NewCoin(DefaultBondDenom, math.NewInt(76052)), + }, + { + name: "want error when current time is before previous time", + annualProvisions: annualProvisions, + current: current, + previous: current.Add(blockInterval), + wantErr: true, + }, + } + for _, tc := range testCases { + minter.AnnualProvisions = tc.annualProvisions + got, err := minter.CalculateBlockProvision(tc.current, tc.previous) + if tc.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + 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) { + minter := DefaultMinter() + current := time.Date(2023, 1, 2, 0, 0, 0, 0, time.UTC) + oneYear := time.Duration(NanosecondsPerYear) + end := current.Add(oneYear) + + totalSupply := math.LegacyNewDec(1_000_000_000_000) // 1 trillion ubbn + annualProvisions := totalSupply.Mul(InitialInflationRateAsDec()) // 80 billion ubbn + minter.AnnualProvisions = annualProvisions + totalBlockProvisions := math.LegacyNewDec(0) + for current.Before(end) { + blockInterval := randomBlockInterval() + previous := current + current = current.Add(blockInterval) + got, err := minter.CalculateBlockProvision(current, previous) + require.NoError(t, err) + totalBlockProvisions = totalBlockProvisions.Add(math.LegacyNewDecFromInt(got.Amount)) + } + + gotError := totalBlockProvisions.Sub(annualProvisions).Abs().Quo(annualProvisions) + wantError := math.LegacyNewDecWithPrec(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 = math.LegacyNewDec(r1.Int63n(1000000)) + current := time.Unix(r1.Int63n(1000000), 0) + previous := current.Add(-time.Second * 15) + + for n := 0; n < b.N; n++ { + _, err := minter.CalculateBlockProvision(current, previous) + require.NoError(b, err) + } +} + +func BenchmarkCalculateInflationRate(b *testing.B) { + b.ReportAllocs() + minter := DefaultMinter() + genesisTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) + + for n := 0; n < b.N; n++ { + ctx := sdk.NewContext(nil, tmproto.Header{Height: int64(n)}, false, nil) + minter.CalculateInflationRate(ctx, genesisTime) + } +} + +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 := time.Duration(NanosecondsPerYear) + 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 000000000..e5e2ff960 --- /dev/null +++ b/x/mint/types/query.pb.go @@ -0,0 +1,1215 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: babylon/mint/v1/query.proto + +package types + +import ( + context "context" + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/types/known/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_bab217370cac4c70, []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 cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=inflation_rate,json=inflationRate,proto3,customtype=cosmossdk.io/math.LegacyDec" 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_bab217370cac4c70, []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_bab217370cac4c70, []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 cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=annual_provisions,json=annualProvisions,proto3,customtype=cosmossdk.io/math.LegacyDec" 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_bab217370cac4c70, []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_bab217370cac4c70, []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_bab217370cac4c70, []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), "babylon.mint.v1.QueryInflationRateRequest") + proto.RegisterType((*QueryInflationRateResponse)(nil), "babylon.mint.v1.QueryInflationRateResponse") + proto.RegisterType((*QueryAnnualProvisionsRequest)(nil), "babylon.mint.v1.QueryAnnualProvisionsRequest") + proto.RegisterType((*QueryAnnualProvisionsResponse)(nil), "babylon.mint.v1.QueryAnnualProvisionsResponse") + proto.RegisterType((*QueryGenesisTimeRequest)(nil), "babylon.mint.v1.QueryGenesisTimeRequest") + proto.RegisterType((*QueryGenesisTimeResponse)(nil), "babylon.mint.v1.QueryGenesisTimeResponse") +} + +func init() { proto.RegisterFile("babylon/mint/v1/query.proto", fileDescriptor_bab217370cac4c70) } + +var fileDescriptor_bab217370cac4c70 = []byte{ + // 501 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcd, 0x6e, 0xd3, 0x40, + 0x14, 0x85, 0x33, 0xfc, 0x2d, 0x26, 0x2d, 0x94, 0x11, 0x12, 0xad, 0x53, 0x1c, 0x70, 0x04, 0x4a, + 0xa9, 0x3a, 0xa3, 0x94, 0x27, 0x20, 0x20, 0xf1, 0x23, 0x16, 0x25, 0xea, 0x8a, 0x4d, 0x34, 0x0e, + 0x53, 0x67, 0x84, 0x3d, 0xd7, 0xc9, 0x8c, 0x23, 0xb2, 0x65, 0x8f, 0x54, 0x09, 0xf1, 0x00, 0xbc, + 0x4d, 0x97, 0x95, 0xba, 0x41, 0x2c, 0x0a, 0x4a, 0x78, 0x10, 0xe4, 0xb1, 0x5d, 0xd2, 0xc4, 0x91, + 0xd2, 0x5d, 0x26, 0xe7, 0xe6, 0x9c, 0x2f, 0xf7, 0x5c, 0x5c, 0xf3, 0xb9, 0x3f, 0x0e, 0x41, 0xb1, + 0x48, 0x2a, 0xc3, 0x46, 0x2d, 0x36, 0x48, 0xc4, 0x70, 0x4c, 0xe3, 0x21, 0x18, 0x20, 0x77, 0x72, + 0x91, 0xa6, 0x22, 0x1d, 0xb5, 0x9c, 0x7b, 0x01, 0x04, 0x60, 0x35, 0x96, 0x7e, 0xca, 0xc6, 0x9c, + 0xed, 0x00, 0x20, 0x08, 0x05, 0xe3, 0xb1, 0x64, 0x5c, 0x29, 0x30, 0xdc, 0x48, 0x50, 0x3a, 0x57, + 0x9d, 0xf9, 0x04, 0x6b, 0x96, 0x69, 0xf5, 0xfc, 0x97, 0xf6, 0xe5, 0x27, 0x47, 0xcc, 0xc8, 0x48, + 0x68, 0xc3, 0xa3, 0x38, 0x1b, 0xf0, 0x6a, 0x78, 0xeb, 0x7d, 0x0a, 0xf4, 0x46, 0x1d, 0x85, 0xd6, + 0xb5, 0xc3, 0x8d, 0xe8, 0x88, 0x41, 0x22, 0xb4, 0xf1, 0xfa, 0xd8, 0x29, 0x13, 0x75, 0x0c, 0x4a, + 0x0b, 0xf2, 0x16, 0xdf, 0x96, 0x85, 0xd0, 0x1d, 0x72, 0x23, 0x36, 0xd1, 0x43, 0xd4, 0x5c, 0x6b, + 0x37, 0x4e, 0xce, 0xeb, 0x95, 0x5f, 0xe7, 0xf5, 0x5a, 0x0f, 0x74, 0x04, 0x5a, 0x7f, 0xfc, 0x44, + 0x25, 0xb0, 0x88, 0x9b, 0x3e, 0x7d, 0x27, 0x02, 0xde, 0x1b, 0xbf, 0x14, 0xbd, 0xce, 0xba, 0x9c, + 0xf5, 0xf4, 0x5c, 0xbc, 0x6d, 0x93, 0x9e, 0x2b, 0x95, 0xf0, 0xf0, 0x60, 0x08, 0x23, 0xa9, 0xd3, + 0xbf, 0x58, 0x90, 0x0c, 0xf0, 0x83, 0x25, 0x7a, 0x0e, 0x73, 0x80, 0xef, 0x72, 0xab, 0x75, 0xe3, + 0x0b, 0xf1, 0x2a, 0x3c, 0x1b, 0x7c, 0xce, 0xd9, 0xdb, 0xc2, 0xf7, 0x6d, 0xe4, 0x2b, 0xa1, 0x84, + 0x96, 0xfa, 0x50, 0x46, 0x17, 0x7b, 0xe9, 0xe2, 0xcd, 0x45, 0x29, 0x07, 0x79, 0x81, 0xd7, 0x82, + 0xec, 0xeb, 0x6e, 0xba, 0x6b, 0xcb, 0x50, 0xdd, 0x77, 0x68, 0x56, 0x04, 0x2d, 0x8a, 0xa0, 0x87, + 0x45, 0x11, 0xed, 0x1b, 0xc7, 0xbf, 0xeb, 0xa8, 0x53, 0x0d, 0xfe, 0x9b, 0xed, 0x9f, 0x5d, 0xc7, + 0x37, 0x6d, 0x02, 0xf9, 0x8e, 0xf0, 0xfa, 0xa5, 0xf5, 0x93, 0xa7, 0x74, 0xee, 0x68, 0xe8, 0xd2, + 0x02, 0x9d, 0xdd, 0x95, 0x66, 0x33, 0x72, 0x6f, 0xf7, 0xcb, 0xd9, 0xdf, 0x6f, 0xd7, 0x1e, 0x93, + 0x06, 0xcb, 0x16, 0x55, 0xdc, 0x93, 0x2f, 0x0c, 0x6f, 0xb1, 0xcb, 0x55, 0x93, 0x1f, 0x08, 0x6f, + 0xcc, 0x97, 0x41, 0xf6, 0xca, 0xe3, 0x96, 0x94, 0xea, 0xd0, 0x55, 0xc7, 0x73, 0x40, 0x6a, 0x01, + 0x9b, 0xe4, 0x49, 0x29, 0xe0, 0x42, 0xfd, 0xe4, 0x2b, 0xc2, 0xd5, 0x99, 0x8a, 0x48, 0xb3, 0x3c, + 0x6f, 0xb1, 0x60, 0x67, 0x67, 0x85, 0xc9, 0x1c, 0x6a, 0xc7, 0x42, 0x35, 0xc8, 0xa3, 0x52, 0xa8, + 0xd9, 0x53, 0x68, 0xbf, 0x3e, 0x99, 0xb8, 0xe8, 0x74, 0xe2, 0xa2, 0x3f, 0x13, 0x17, 0x1d, 0x4f, + 0xdd, 0xca, 0xe9, 0xd4, 0xad, 0xfc, 0x9c, 0xba, 0x95, 0x0f, 0x34, 0x90, 0xa6, 0x9f, 0xf8, 0xb4, + 0x07, 0x11, 0xcb, 0x93, 0x43, 0xee, 0xeb, 0x3d, 0x09, 0xc5, 0x93, 0x7d, 0xce, 0x8c, 0xcd, 0x38, + 0x16, 0xda, 0xbf, 0x65, 0xcf, 0xe8, 0xd9, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xa4, 0xd5, + 0x0a, 0x5d, 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, "/babylon.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, "/babylon.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, "/babylon.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: "/babylon.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: "/babylon.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: "/babylon.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: "babylon.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: "babylon/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_cosmos_gogoproto_types.StdTimeMarshalTo(*m.GenesisTime, dAtA[i-github_com_cosmos_gogoproto_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_cosmos_gogoproto_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_cosmos_gogoproto_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 000000000..d9ca42c48 --- /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: babylon/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 +)