mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 22:37:26 +00:00 
			
		
		
		
	harvest-fix: check for status other than bonded, add staking tests (#677)
* fix: check for any status other than bonded * Add harvest staking tests (#680) * refactor config initialization * refactor delegator rewards test, add tests * fix share to token calculation, add unbonding test * remove dead link Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									e0771cc9e8
								
							
						
					
					
						commit
						69512d508b
					
				| @ -40,7 +40,6 @@ Listed in alphabetical order. | ||||
| - [OKEx Pool](https://www.okex.com/pool) | ||||
| - [P2P](https://p2p.org/) | ||||
| - [SNZ Pool](https://snzholding.com/pool.html) | ||||
| - [Sikka](https://www.sikka.tech/) | ||||
| - [StakeWith.Us](https://www.stakewith.us/) | ||||
| - [Staked](https://staked.us/) | ||||
| - [stake.fish](https://stake.fish/en/) | ||||
|  | ||||
| @ -243,8 +243,7 @@ func (suite *KeeperTestSuite) TestClaim() { | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			// create new app with one funded account
 | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tc.args.blockTime}) | ||||
|  | ||||
| @ -111,8 +111,7 @@ func (suite *KeeperTestSuite) TestDeposit() { | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			// create new app with one funded account
 | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()}) | ||||
| @ -279,8 +278,7 @@ func (suite *KeeperTestSuite) TestWithdraw() { | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			// create new app with one funded account
 | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()}) | ||||
|  | ||||
| @ -29,6 +29,9 @@ type KeeperTestSuite struct { | ||||
| 
 | ||||
| // The default state used by each test
 | ||||
| func (suite *KeeperTestSuite) SetupTest() { | ||||
| 	config := sdk.GetConfig() | ||||
| 	app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 	tApp := app.NewTestApp() | ||||
| 	ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()}) | ||||
| 	tApp.InitializeFromGenesisStates() | ||||
|  | ||||
| @ -125,11 +125,11 @@ func (k Keeper) ApplyDelegationRewards(ctx sdk.Context, denom string) { | ||||
| 		if validator.GetTokens().IsZero() { | ||||
| 			return false | ||||
| 		} | ||||
| 		// don't include a validator if it's unbonded - ie delegators don't accumulate rewards when delegated to an unbonded validator
 | ||||
| 		if validator.GetStatus() == sdk.Unbonded { | ||||
| 		// don't include a validator if it's unbonded or unbonding- ie delegators don't accumulate rewards when delegated to an unbonded/slashed validator
 | ||||
| 		if validator.GetStatus() != sdk.Bonded { | ||||
| 			return false | ||||
| 		} | ||||
| 		sharesToTokens[validator.GetOperator().String()] = (validator.GetDelegatorShares()).Quo(sdk.NewDecFromInt(validator.GetTokens())) | ||||
| 		sharesToTokens[validator.GetOperator().String()] = sdk.NewDecFromInt(validator.GetTokens()).Quo(validator.GetDelegatorShares()) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
|  | ||||
| @ -1,15 +1,19 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||
| 	"github.com/cosmos/cosmos-sdk/x/staking" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 	abci "github.com/tendermint/tendermint/abci/types" | ||||
| 	"github.com/tendermint/tendermint/crypto" | ||||
| 	"github.com/tendermint/tendermint/crypto/ed25519" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/harvest/keeper" | ||||
| 	"github.com/kava-labs/kava/x/harvest/types" | ||||
| ) | ||||
| 
 | ||||
| @ -56,8 +60,6 @@ func (suite *KeeperTestSuite) TestApplyDepositRewards() { | ||||
| 	} | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tc.args.blockTime}) | ||||
| @ -94,101 +96,369 @@ func (suite *KeeperTestSuite) TestApplyDepositRewards() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestApplyDelegatorRewards() { | ||||
| 	type args struct { | ||||
| 		delegator                sdk.AccAddress | ||||
| 		delegatorCoins           sdk.Coins | ||||
| 		delegationAmount         sdk.Coin | ||||
| 		totalBonded              sdk.Coin | ||||
| 		rewardRate               sdk.Coin | ||||
| 		depositType              types.DepositType | ||||
| 		previousDistributionTime time.Time | ||||
| 		blockTime                time.Time | ||||
| 		expectedClaimBalance     sdk.Coin | ||||
| func TestApplyDelegatorRewardsTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(DelegatorRewardsTestSuite)) | ||||
| } | ||||
| 
 | ||||
| type DelegatorRewardsTestSuite struct { | ||||
| 	suite.Suite | ||||
| 
 | ||||
| 	validatorAddrs []sdk.ValAddress | ||||
| 	delegatorAddrs []sdk.AccAddress | ||||
| 
 | ||||
| 	keeper        keeper.Keeper | ||||
| 	stakingKeeper staking.Keeper | ||||
| 	app           app.TestApp | ||||
| 	rewardRate    int64 | ||||
| } | ||||
| 
 | ||||
| // The default state used by each test
 | ||||
| func (suite *DelegatorRewardsTestSuite) SetupTest() { | ||||
| 	config := sdk.GetConfig() | ||||
| 	app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 	_, allAddrs := app.GeneratePrivKeyAddressPairs(10) | ||||
| 	suite.delegatorAddrs = allAddrs[:5] | ||||
| 	for _, a := range allAddrs[5:] { | ||||
| 		suite.validatorAddrs = append(suite.validatorAddrs, sdk.ValAddress(a)) | ||||
| 	} | ||||
| 	type errArgs struct { | ||||
| 		expectPanic bool | ||||
| 		contains    string | ||||
| 
 | ||||
| 	suite.app = app.NewTestApp() | ||||
| 
 | ||||
| 	suite.rewardRate = 500 | ||||
| 
 | ||||
| 	suite.app.InitializeFromGenesisStates( | ||||
| 		equalCoinsAuthGenState(allAddrs, cs(c("ukava", 5_000_000))), | ||||
| 		stakingGenesisState(), | ||||
| 		harvestGenesisState(c("hard", suite.rewardRate)), | ||||
| 	) | ||||
| 
 | ||||
| 	suite.keeper = suite.app.GetHarvestKeeper() | ||||
| 	suite.stakingKeeper = suite.app.GetStakingKeeper() | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) TestSlash() { | ||||
| 
 | ||||
| 	blockTime := time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC) | ||||
| 	ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: blockTime}) | ||||
| 	const rewardDuration = 5 | ||||
| 	suite.keeper.SetPreviousDelegationDistribution(ctx, blockTime.Add(-1*rewardDuration*time.Second), "ukava") | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[0], c("ukava", 5_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.slashValidator(ctx, suite.validatorAddrs[0], "0.05"), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	// Run function under test
 | ||||
| 	suite.keeper.ApplyDelegationRewards(ctx, "ukava") | ||||
| 
 | ||||
| 	// Check claim amounts
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, sdk.AccAddress(suite.validatorAddrs[0]), c("hard", suite.rewardRate*rewardDuration)), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) TestUndelegation() { | ||||
| 
 | ||||
| 	blockTime := time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC) | ||||
| 	ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: blockTime}) | ||||
| 	const rewardDuration = 5 | ||||
| 	suite.keeper.SetPreviousDelegationDistribution(ctx, blockTime.Add(-1*rewardDuration*time.Second), "ukava") | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgUndelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	// Run function under test
 | ||||
| 	suite.keeper.ApplyDelegationRewards(ctx, "ukava") | ||||
| 
 | ||||
| 	// Check claim amounts
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, sdk.AccAddress(suite.validatorAddrs[0]), c("hard", suite.rewardRate*rewardDuration)), | ||||
| 	) | ||||
| 	suite.Require().False( | ||||
| 		suite.kavaClaimExists(ctx, suite.delegatorAddrs[0]), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) TestUnevenNumberDelegations() { | ||||
| 
 | ||||
| 	// Setup a context
 | ||||
| 	blockTime := time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC) | ||||
| 	ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: blockTime}) | ||||
| 	const rewardDuration = 5 | ||||
| 	suite.keeper.SetPreviousDelegationDistribution(ctx, blockTime.Add(-1*rewardDuration*time.Second), "ukava") | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[1], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	// Run function under test
 | ||||
| 	suite.keeper.ApplyDelegationRewards(ctx, "ukava") | ||||
| 
 | ||||
| 	// Check claim amounts
 | ||||
| 	expectedReward := suite.rewardRate * rewardDuration / 3 // floor division
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, sdk.AccAddress(suite.validatorAddrs[0]), c("hard", expectedReward)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, suite.delegatorAddrs[0], c("hard", expectedReward)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, suite.delegatorAddrs[1], c("hard", expectedReward)), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) TestSlashWithUndelegated() { | ||||
| 
 | ||||
| 	// Setup a context
 | ||||
| 	blockTime := time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC) | ||||
| 	ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: blockTime}) | ||||
| 	const rewardDuration = 5 | ||||
| 	suite.keeper.SetPreviousDelegationDistribution(ctx, blockTime.Add(-1*rewardDuration*time.Second), "ukava") | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[1], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgUndelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.slashValidator(ctx, suite.validatorAddrs[0], "0.05"), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	// Run function under test
 | ||||
| 	suite.keeper.ApplyDelegationRewards(ctx, "ukava") | ||||
| 
 | ||||
| 	// Check claim amounts
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, sdk.AccAddress(suite.validatorAddrs[0]), c("hard", suite.rewardRate*rewardDuration/2)), | ||||
| 	) | ||||
| 	suite.Require().False( | ||||
| 		suite.kavaClaimExists(ctx, suite.delegatorAddrs[0]), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, suite.delegatorAddrs[1], c("hard", suite.rewardRate*rewardDuration/2)), | ||||
| 	) | ||||
| } | ||||
| func (suite *DelegatorRewardsTestSuite) TestUnbondingValidator() { | ||||
| 
 | ||||
| 	// Setup a context
 | ||||
| 	blockTime := time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC) | ||||
| 	ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: blockTime}) | ||||
| 	const rewardDuration = 5 | ||||
| 	suite.keeper.SetPreviousDelegationDistribution(ctx, blockTime.Add(-1*rewardDuration*time.Second), "ukava") | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgCreateValidator(ctx, suite.validatorAddrs[1], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[0], suite.validatorAddrs[0], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.deliverMsgDelegate(ctx, suite.delegatorAddrs[1], suite.validatorAddrs[1], c("ukava", 1_000_000)), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	suite.Require().NoError( | ||||
| 		// jail the validator to put it into an unbonding state
 | ||||
| 		suite.jailValidator(ctx, suite.validatorAddrs[0]), | ||||
| 	) | ||||
| 	staking.EndBlocker(ctx, suite.stakingKeeper) | ||||
| 
 | ||||
| 	// Run function under test
 | ||||
| 	suite.keeper.ApplyDelegationRewards(ctx, "ukava") | ||||
| 
 | ||||
| 	// Check claim amounts
 | ||||
| 	suite.Require().False( | ||||
| 		// validator 0 will be unbonding and should not receive rewards
 | ||||
| 		suite.kavaClaimExists(ctx, sdk.AccAddress(suite.validatorAddrs[0])), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, sdk.AccAddress(suite.validatorAddrs[1]), c("hard", suite.rewardRate*rewardDuration/2)), | ||||
| 	) | ||||
| 	suite.Require().False( | ||||
| 		// delegations to unbonding validators and should not receive rewards
 | ||||
| 		suite.kavaClaimExists(ctx, suite.delegatorAddrs[0]), | ||||
| 	) | ||||
| 	suite.Require().NoError( | ||||
| 		suite.verifyKavaClaimAmount(ctx, suite.delegatorAddrs[1], c("hard", suite.rewardRate*rewardDuration/2)), | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) deliverMsgCreateValidator(ctx sdk.Context, address sdk.ValAddress, selfDelegation sdk.Coin) error { | ||||
| 	msg := staking.NewMsgCreateValidator( | ||||
| 		address, | ||||
| 		ed25519.GenPrivKey().PubKey(), | ||||
| 		selfDelegation, | ||||
| 		staking.Description{}, | ||||
| 		staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), | ||||
| 		sdk.NewInt(1_000_000), | ||||
| 	) | ||||
| 	handleStakingMsg := staking.NewHandler(suite.stakingKeeper) | ||||
| 	_, err := handleStakingMsg(ctx, msg) | ||||
| 	return err | ||||
| } | ||||
| func (suite *DelegatorRewardsTestSuite) deliverMsgDelegate(ctx sdk.Context, delegator sdk.AccAddress, validator sdk.ValAddress, amount sdk.Coin) error { | ||||
| 	msg := staking.NewMsgDelegate( | ||||
| 		delegator, | ||||
| 		validator, | ||||
| 		amount, | ||||
| 	) | ||||
| 	handleStakingMsg := staking.NewHandler(suite.stakingKeeper) | ||||
| 	_, err := handleStakingMsg(ctx, msg) | ||||
| 	return err | ||||
| } | ||||
| func (suite *DelegatorRewardsTestSuite) deliverMsgUndelegate(ctx sdk.Context, delegator sdk.AccAddress, validator sdk.ValAddress, amount sdk.Coin) error { | ||||
| 	msg := staking.NewMsgUndelegate( | ||||
| 		delegator, | ||||
| 		validator, | ||||
| 		amount, | ||||
| 	) | ||||
| 	handleStakingMsg := staking.NewHandler(suite.stakingKeeper) | ||||
| 	_, err := handleStakingMsg(ctx, msg) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (suite *DelegatorRewardsTestSuite) slashValidator(ctx sdk.Context, validator sdk.ValAddress, slashPercent string) error { | ||||
| 	// Assume slashable offence occurred at block 1. Note this might cause problems if tests are running at a block height higher than the unbonding period (default 3 weeks)
 | ||||
| 	const infractionHeight int64 = 1 | ||||
| 
 | ||||
| 	val, found := suite.stakingKeeper.GetValidator(ctx, validator) | ||||
| 	if !found { | ||||
| 		return fmt.Errorf("can't find validator in state") | ||||
| 	} | ||||
| 	type testCase struct { | ||||
| 		name    string | ||||
| 		args    args | ||||
| 		errArgs errArgs | ||||
| 	suite.stakingKeeper.Slash( | ||||
| 		ctx, | ||||
| 		sdk.GetConsAddress(val.ConsPubKey), | ||||
| 		infractionHeight, | ||||
| 		val.GetConsensusPower(), | ||||
| 		sdk.MustNewDecFromStr(slashPercent), | ||||
| 	) | ||||
| 	return nil | ||||
| } | ||||
| func (suite *DelegatorRewardsTestSuite) jailValidator(ctx sdk.Context, validator sdk.ValAddress) error { | ||||
| 	val, found := suite.stakingKeeper.GetValidator(ctx, validator) | ||||
| 	if !found { | ||||
| 		return fmt.Errorf("can't find validator in state") | ||||
| 	} | ||||
| 	testCases := []testCase{ | ||||
| 		{ | ||||
| 			name: "distribute rewards", | ||||
| 			args: args{ | ||||
| 				delegator:                sdk.AccAddress(crypto.AddressHash([]byte("test"))), | ||||
| 				delegatorCoins:           cs(c("ukava", 1000)), | ||||
| 				rewardRate:               c("hard", 500), | ||||
| 				delegationAmount:         c("ukava", 100), | ||||
| 				totalBonded:              c("ukava", 900), | ||||
| 				depositType:              types.Stake, | ||||
| 				previousDistributionTime: time.Date(2020, 11, 1, 13, 59, 50, 0, time.UTC), | ||||
| 				blockTime:                time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC), | ||||
| 				expectedClaimBalance:     c("hard", 500), | ||||
| 	suite.stakingKeeper.Jail(ctx, sdk.GetConsAddress(val.ConsPubKey)) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // verifyKavaClaimAmount looks up a ukava claim and checks the claim amount is equal to an expected value
 | ||||
| func (suite *DelegatorRewardsTestSuite) verifyKavaClaimAmount(ctx sdk.Context, owner sdk.AccAddress, expectedAmount sdk.Coin) error { | ||||
| 	claim, found := suite.keeper.GetClaim(ctx, owner, "ukava", types.Stake) | ||||
| 	if !found { | ||||
| 		return fmt.Errorf("could not find claim") | ||||
| 	} | ||||
| 	if !expectedAmount.IsEqual(claim.Amount) { | ||||
| 		return fmt.Errorf("expected claim amount (%s) != actual claim amount (%s)", expectedAmount, claim.Amount) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // kavaClaimExists checks the store for a ukava claim
 | ||||
| func (suite *DelegatorRewardsTestSuite) kavaClaimExists(ctx sdk.Context, owner sdk.AccAddress) bool { | ||||
| 	_, found := suite.keeper.GetClaim(ctx, owner, "ukava", types.Stake) | ||||
| 	return found | ||||
| } | ||||
| 
 | ||||
| func harvestGenesisState(rewardRate sdk.Coin) app.GenesisState { | ||||
| 	genState := types.NewGenesisState( | ||||
| 		types.NewParams( | ||||
| 			true, | ||||
| 			types.DistributionSchedules{ | ||||
| 				types.NewDistributionSchedule( | ||||
| 					true, | ||||
| 					"bnb", | ||||
| 					time.Date(2020, 10, 8, 14, 0, 0, 0, time.UTC), | ||||
| 					time.Date(2020, 11, 22, 14, 0, 0, 0, time.UTC), | ||||
| 					rewardRate, | ||||
| 					time.Date(2021, 11, 22, 14, 0, 0, 0, time.UTC), | ||||
| 					types.Multipliers{ | ||||
| 						types.NewMultiplier(types.Small, 0, sdk.MustNewDecFromStr("0.33")), | ||||
| 						types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.5")), | ||||
| 						types.NewMultiplier(types.Large, 24, sdk.OneDec()), | ||||
| 					}, | ||||
| 				), | ||||
| 			}, | ||||
| 			errArgs: errArgs{ | ||||
| 				expectPanic: false, | ||||
| 				contains:    "", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tc.args.blockTime}) | ||||
| 			authGS := app.NewAuthGenState([]sdk.AccAddress{tc.args.delegator, sdk.AccAddress(crypto.AddressHash([]byte("other_delegator")))}, []sdk.Coins{tc.args.delegatorCoins, cs(tc.args.totalBonded)}) | ||||
| 			harvestGS := types.NewGenesisState(types.NewParams( | ||||
| 				true, | ||||
| 				types.DistributionSchedules{ | ||||
| 					types.NewDistributionSchedule(true, "bnb", time.Date(2020, 10, 8, 14, 0, 0, 0, time.UTC), time.Date(2020, 11, 22, 14, 0, 0, 0, time.UTC), tc.args.rewardRate, time.Date(2021, 11, 22, 14, 0, 0, 0, time.UTC), types.Multipliers{types.NewMultiplier(types.Small, 0, sdk.MustNewDecFromStr("0.33")), types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.5")), types.NewMultiplier(types.Large, 24, sdk.OneDec())}), | ||||
| 				}, | ||||
| 				types.DelegatorDistributionSchedules{types.NewDelegatorDistributionSchedule( | ||||
| 					types.NewDistributionSchedule(true, "ukava", time.Date(2020, 10, 8, 14, 0, 0, 0, time.UTC), time.Date(2025, 10, 8, 14, 0, 0, 0, time.UTC), tc.args.rewardRate, time.Date(2026, 10, 8, 14, 0, 0, 0, time.UTC), types.Multipliers{types.NewMultiplier(types.Small, 0, sdk.MustNewDecFromStr("0.33")), types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.5")), types.NewMultiplier(types.Large, 24, sdk.OneDec())}), | ||||
| 			types.DelegatorDistributionSchedules{ | ||||
| 				types.NewDelegatorDistributionSchedule( | ||||
| 					types.NewDistributionSchedule( | ||||
| 						true, | ||||
| 						"ukava", | ||||
| 						time.Date(2020, 10, 8, 14, 0, 0, 0, time.UTC), | ||||
| 						time.Date(2025, 10, 8, 14, 0, 0, 0, time.UTC), | ||||
| 						rewardRate, | ||||
| 						time.Date(2026, 10, 8, 14, 0, 0, 0, time.UTC), | ||||
| 						types.Multipliers{ | ||||
| 							types.NewMultiplier(types.Small, 0, sdk.MustNewDecFromStr("0.33")), | ||||
| 							types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.5")), | ||||
| 							types.NewMultiplier(types.Large, 24, sdk.OneDec()), | ||||
| 						}, | ||||
| 					), | ||||
| 					time.Hour*24, | ||||
| 				), | ||||
| 				}, | ||||
| 			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes) | ||||
| 			tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)}) | ||||
| 			keeper := tApp.GetHarvestKeeper() | ||||
| 			keeper.SetPreviousDelegationDistribution(ctx, tc.args.previousDistributionTime, "ukava") | ||||
| 			stakingKeeper := tApp.GetStakingKeeper() | ||||
| 			stakingParams := stakingKeeper.GetParams(ctx) | ||||
| 			stakingParams.BondDenom = "ukava" | ||||
| 			stakingKeeper.SetParams(ctx, stakingParams) | ||||
| 			validatorPubKey := ed25519.GenPrivKey().PubKey() | ||||
| 			validator := stakingtypes.NewValidator(sdk.ValAddress(validatorPubKey.Address()), validatorPubKey, stakingtypes.Description{}) | ||||
| 			validator.Status = sdk.Bonded | ||||
| 			stakingKeeper.SetValidator(ctx, validator) | ||||
| 			stakingKeeper.SetValidatorByConsAddr(ctx, validator) | ||||
| 			stakingKeeper.SetNewValidatorByPowerIndex(ctx, validator) | ||||
| 			// call the after-creation hook
 | ||||
| 			stakingKeeper.AfterValidatorCreated(ctx, validator.OperatorAddress) | ||||
| 			_, err := stakingKeeper.Delegate(ctx, tc.args.delegator, tc.args.delegationAmount.Amount, sdk.Unbonded, validator, true) | ||||
| 			suite.Require().NoError(err) | ||||
| 			stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) | ||||
| 			validator, f := stakingKeeper.GetValidator(ctx, validator.OperatorAddress) | ||||
| 			suite.Require().True(f) | ||||
| 			_, err = stakingKeeper.Delegate(ctx, sdk.AccAddress(crypto.AddressHash([]byte("other_delegator"))), tc.args.totalBonded.Amount, sdk.Unbonded, validator, true) | ||||
| 			suite.Require().NoError(err) | ||||
| 			stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) | ||||
| 			suite.app = tApp | ||||
| 			suite.ctx = ctx | ||||
| 			suite.keeper = keeper | ||||
| 			}, | ||||
| 		), | ||||
| 		types.DefaultPreviousBlockTime, | ||||
| 		types.DefaultDistributionTimes, | ||||
| 	) | ||||
| 	return app.GenesisState{ | ||||
| 		types.ModuleName: types.ModuleCdc.MustMarshalJSON(genState), | ||||
| 	} | ||||
| 
 | ||||
| 			if tc.errArgs.expectPanic { | ||||
| 				suite.Require().Panics(func() { suite.keeper.ApplyDelegationRewards(suite.ctx, suite.keeper.BondDenom(suite.ctx)) }) | ||||
| 			} else { | ||||
| 				suite.Require().NotPanics(func() { suite.keeper.ApplyDelegationRewards(suite.ctx, suite.keeper.BondDenom(suite.ctx)) }) | ||||
| 				claim, f := suite.keeper.GetClaim(suite.ctx, tc.args.delegator, tc.args.delegationAmount.Denom, tc.args.depositType) | ||||
| 				suite.Require().True(f) | ||||
| 				suite.Require().Equal(tc.args.expectedClaimBalance, claim.Amount) | ||||
| 			} | ||||
| 		}) | ||||
| } | ||||
| 
 | ||||
| func stakingGenesisState() app.GenesisState { | ||||
| 	genState := staking.DefaultGenesisState() | ||||
| 	genState.Params.BondDenom = "ukava" | ||||
| 	return app.GenesisState{ | ||||
| 		staking.ModuleName: staking.ModuleCdc.MustMarshalJSON(genState), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // equalCoinsAuthGenState returns an auth genesis state with the same coins for each account
 | ||||
| func equalCoinsAuthGenState(addresses []sdk.AccAddress, coins sdk.Coins) app.GenesisState { | ||||
| 	coinsList := []sdk.Coins{} | ||||
| 	for range addresses { | ||||
| 		coinsList = append(coinsList, coins) | ||||
| 	} | ||||
| 	return app.NewAuthGenState(addresses, coinsList) | ||||
| } | ||||
|  | ||||
| @ -6,10 +6,11 @@ import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/cosmos/cosmos-sdk/x/auth" | ||||
| 	"github.com/cosmos/cosmos-sdk/x/auth/vesting" | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/harvest/types" | ||||
| 	abci "github.com/tendermint/tendermint/abci/types" | ||||
| 	"github.com/tendermint/tendermint/crypto" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/harvest/types" | ||||
| ) | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestSendTimeLockedCoinsToAccount() { | ||||
| @ -273,8 +274,7 @@ func (suite *KeeperTestSuite) TestSendTimeLockedCoinsToAccount() { | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			// create new app with one funded account
 | ||||
| 			config := sdk.GetConfig() | ||||
| 			app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 			// Initialize test app and set context
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tc.args.blockTime}) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Kevin Davis
						Kevin Davis