diff --git a/app/export.go b/app/export.go index e4a5725a..9846196e 100644 --- a/app/export.go +++ b/app/export.go @@ -17,6 +17,7 @@ import ( func (app *App) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, ) (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { // as if they could withdraw from the start of the next block + // block time is not available and defaults to Jan 1st, 0001 ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()}) if forZeroHeight { diff --git a/migrate/v0_13/migrate.go b/migrate/v0_13/migrate.go index cbc402e9..470e8cfa 100644 --- a/migrate/v0_13/migrate.go +++ b/migrate/v0_13/migrate.go @@ -296,24 +296,24 @@ func Incentive(hardGS v0_11hard.GenesisState, incentiveGS v0_11incentive.Genesis usdxGenAccumulationTimes := v0_13incentive.GenesisAccumulationTimes{} for _, rp := range params.USDXMintingRewardPeriods { - gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime, sdk.ZeroDec()) + gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime) usdxGenAccumulationTimes = append(usdxGenAccumulationTimes, gat) } hardSupplyGenAccumulationTimes := v0_13incentive.GenesisAccumulationTimes{} for _, rp := range params.HardSupplyRewardPeriods { - gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime, sdk.ZeroDec()) + gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime) hardSupplyGenAccumulationTimes = append(hardSupplyGenAccumulationTimes, gat) } hardBorrowGenAccumulationTimes := v0_13incentive.GenesisAccumulationTimes{} for _, rp := range params.HardBorrowRewardPeriods { - gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime, sdk.ZeroDec()) + gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime) hardBorrowGenAccumulationTimes = append(hardBorrowGenAccumulationTimes, gat) } hardDelegatorGenAccumulationTimes := v0_13incentive.GenesisAccumulationTimes{} for _, rp := range params.HardDelegatorRewardPeriods { - gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime, sdk.ZeroDec()) + gat := v0_13incentive.NewGenesisAccumulationTime(rp.CollateralType, GenesisTime) hardDelegatorGenAccumulationTimes = append(hardDelegatorGenAccumulationTimes, gat) } diff --git a/x/cdp/genesis.go b/x/cdp/genesis.go index 6b9016bb..61ff9ce0 100644 --- a/x/cdp/genesis.go +++ b/x/cdp/genesis.go @@ -115,7 +115,14 @@ func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState { if !found { interestFactor = sdk.OneDec() } - previousAccumTime, _ := k.GetPreviousAccrualTime(ctx, cp.Type) + // Governance param changes happen in the end blocker. If a new collateral type is added and then the chain + // is exported before the BeginBlocker can run, previous accrual time won't be found. We can't set it to + // current block time because it is not available in the export ctx. We should panic instead of exporting + // bad state. + previousAccumTime, f := k.GetPreviousAccrualTime(ctx, cp.Type) + if !f { + panic(fmt.Sprintf("expected previous accrual time to be set in state for %s", cp.Type)) + } previousAccumTimes = append(previousAccumTimes, types.NewGenesisAccumulationTime(cp.Type, previousAccumTime, interestFactor)) tp := k.GetTotalPrincipal(ctx, cp.Type, types.DefaultStableDenom) diff --git a/x/hard/genesis.go b/x/hard/genesis.go index 345934c9..b8ae2977 100644 --- a/x/hard/genesis.go +++ b/x/hard/genesis.go @@ -89,15 +89,20 @@ func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState { for _, mm := range params.MoneyMarkets { supplyFactor, f := k.GetSupplyInterestFactor(ctx, mm.Denom) if !f { - supplyFactor = sdk.ZeroDec() + supplyFactor = sdk.OneDec() } borrowFactor, f := k.GetBorrowInterestFactor(ctx, mm.Denom) if !f { - borrowFactor = sdk.ZeroDec() + borrowFactor = sdk.OneDec() } previousAccrualTime, f := k.GetPreviousAccrualTime(ctx, mm.Denom) if !f { - previousAccrualTime = ctx.BlockTime() + // Goverance adds new params at end of block, but mm's previous accrual time is set in begin blocker. + // If a new money market is added and chain is exported before begin blocker runs, then the previous + // accrual time will not be found. We can't set it here because our ctx doesn't contain current block + // time; if we set it to ctx.BlockTime() then on the next block it could accrue interest from Jan 1st + // 0001 to now. To avoid setting up a bad state, we panic. + panic(fmt.Sprintf("expected previous accrual time to be set in state for %s", mm.Denom)) } gat := types.NewGenesisAccumulationTime(mm.Denom, previousAccrualTime, supplyFactor, borrowFactor) gats = append(gats, gat) diff --git a/x/incentive/genesis.go b/x/incentive/genesis.go index 85aa7d8b..036c217b 100644 --- a/x/incentive/genesis.go +++ b/x/incentive/genesis.go @@ -56,7 +56,6 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, supplyKeeper types.SupplyKeep for _, gat := range gs.USDXAccumulationTimes { k.SetPreviousUSDXMintingAccrualTime(ctx, gat.CollateralType, gat.PreviousAccumulationTime) - k.SetUSDXMintingRewardFactor(ctx, gat.CollateralType, gat.RewardFactor) } for _, gat := range gs.HardSupplyAccumulationTimes { @@ -147,20 +146,46 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { synchronizedHardClaims = append(synchronizedHardClaims, claim) } - var gats GenesisAccumulationTimes - + var usdxMintingGats GenesisAccumulationTimes for _, rp := range params.USDXMintingRewardPeriods { pat, found := k.GetPreviousUSDXMintingAccrualTime(ctx, rp.CollateralType) if !found { - pat = ctx.BlockTime() + panic(fmt.Sprintf("expected previous usdx minting reward accrual time to be set in state for %s", rp.CollateralType)) } - factor, found := k.GetUSDXMintingRewardFactor(ctx, rp.CollateralType) - if !found { - factor = sdk.ZeroDec() - } - gat := types.NewGenesisAccumulationTime(rp.CollateralType, pat, factor) - gats = append(gats, gat) + gat := types.NewGenesisAccumulationTime(rp.CollateralType, pat) + usdxMintingGats = append(usdxMintingGats, gat) } - return types.NewGenesisState(params, gats, DefaultGenesisAccumulationTimes, DefaultGenesisAccumulationTimes, DefaultGenesisAccumulationTimes, synchronizedUsdxClaims, synchronizedHardClaims) + var hardSupplyGats GenesisAccumulationTimes + for _, rp := range params.HardSupplyRewardPeriods { + pat, found := k.GetPreviousHardSupplyRewardAccrualTime(ctx, rp.CollateralType) + if !found { + panic(fmt.Sprintf("expected previous hard supply reward accrual time to be set in state for %s", rp.CollateralType)) + } + gat := types.NewGenesisAccumulationTime(rp.CollateralType, pat) + hardSupplyGats = append(hardSupplyGats, gat) + } + + var hardBorrowGats GenesisAccumulationTimes + for _, rp := range params.HardBorrowRewardPeriods { + pat, found := k.GetPreviousHardBorrowRewardAccrualTime(ctx, rp.CollateralType) + if !found { + panic(fmt.Sprintf("expected previous hard borrow reward accrual time to be set in state for %s", rp.CollateralType)) + } + gat := types.NewGenesisAccumulationTime(rp.CollateralType, pat) + hardBorrowGats = append(hardBorrowGats, gat) + } + + var hardDelegatorGats GenesisAccumulationTimes + for _, rp := range params.HardDelegatorRewardPeriods { + pat, found := k.GetPreviousHardDelegatorRewardAccrualTime(ctx, rp.CollateralType) + if !found { + panic(fmt.Sprintf("expected previous hard delegator reward accrual time to be set in state for %s", rp.CollateralType)) + } + gat := types.NewGenesisAccumulationTime(rp.CollateralType, pat) + hardDelegatorGats = append(hardDelegatorGats, gat) + } + + return types.NewGenesisState(params, usdxMintingGats, hardSupplyGats, + hardBorrowGats, hardDelegatorGats, synchronizedUsdxClaims, synchronizedHardClaims) } diff --git a/x/incentive/integration_test.go b/x/incentive/integration_test.go index d551d498..9778cf6b 100644 --- a/x/incentive/integration_test.go +++ b/x/incentive/integration_test.go @@ -149,7 +149,6 @@ func NewIncentiveGenState(previousAccumTime, endTime time.Time, rewardPeriods .. incentive.NewGenesisAccumulationTime( rp.CollateralType, previousAccumTime, - sdk.ZeroDec(), ), ) } diff --git a/x/incentive/types/genesis.go b/x/incentive/types/genesis.go index d508bc2d..888597bb 100644 --- a/x/incentive/types/genesis.go +++ b/x/incentive/types/genesis.go @@ -4,8 +4,6 @@ import ( "bytes" "fmt" "time" - - sdk "github.com/cosmos/cosmos-sdk/types" ) // GenesisState is the state that must be provided at genesis. @@ -86,15 +84,13 @@ func (gs GenesisState) IsEmpty() bool { type GenesisAccumulationTime struct { CollateralType string `json:"collateral_type" yaml:"collateral_type"` PreviousAccumulationTime time.Time `json:"previous_accumulation_time" yaml:"previous_accumulation_time"` - RewardFactor sdk.Dec `json:"reward_factor" yaml:"reward_factor"` } // NewGenesisAccumulationTime returns a new GenesisAccumulationTime -func NewGenesisAccumulationTime(ctype string, prevTime time.Time, factor sdk.Dec) GenesisAccumulationTime { +func NewGenesisAccumulationTime(ctype string, prevTime time.Time) GenesisAccumulationTime { return GenesisAccumulationTime{ CollateralType: ctype, PreviousAccumulationTime: prevTime, - RewardFactor: factor, } } @@ -113,8 +109,8 @@ func (gats GenesisAccumulationTimes) Validate() error { // Validate performs validation of GenesisAccumulationTime func (gat GenesisAccumulationTime) Validate() error { - if gat.RewardFactor.LT(sdk.ZeroDec()) { - return fmt.Errorf("reward factor should be ≥ 0.0, is %s for %s", gat.RewardFactor, gat.CollateralType) + if len(gat.CollateralType) == 0 { + return fmt.Errorf("genesis accumulation time's collateral type must be defined") } return nil } diff --git a/x/incentive/types/genesis_test.go b/x/incentive/types/genesis_test.go index bfcc921f..28ef5d39 100644 --- a/x/incentive/types/genesis_test.go +++ b/x/incentive/types/genesis_test.go @@ -63,7 +63,6 @@ func TestGenesisStateValidate(t *testing.T) { genAccTimes: GenesisAccumulationTimes{GenesisAccumulationTime{ CollateralType: "bnb-a", PreviousAccumulationTime: time.Date(2020, 10, 15, 14, 0, 0, 0, time.UTC), - RewardFactor: sdk.ZeroDec(), }}, claims: USDXMintingClaims{ { @@ -91,15 +90,15 @@ func TestGenesisStateValidate(t *testing.T) { params: DefaultParams(), genAccTimes: GenesisAccumulationTimes{ { - CollateralType: "btcb-a", - RewardFactor: sdk.MustNewDecFromStr("-0.1"), + CollateralType: "", + PreviousAccumulationTime: time.Date(2020, 10, 15, 14, 0, 0, 0, time.UTC), }, }, claims: DefaultUSDXClaims, }, errArgs: errArgs{ expectPass: false, - contains: "reward factor should be ≥ 0.0", + contains: "collateral type must be defined", }, }, {