github.com/Finschia/finschia-sdk@v0.48.1/x/staking/genesis_test.go (about) 1 package staking_test 2 3 import ( 4 "fmt" 5 "log" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 abci "github.com/tendermint/tendermint/abci/types" 11 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 12 13 codectypes "github.com/Finschia/finschia-sdk/codec/types" 14 "github.com/Finschia/finschia-sdk/crypto/keys/ed25519" 15 "github.com/Finschia/finschia-sdk/simapp" 16 sdk "github.com/Finschia/finschia-sdk/types" 17 "github.com/Finschia/finschia-sdk/x/staking" 18 "github.com/Finschia/finschia-sdk/x/staking/teststaking" 19 "github.com/Finschia/finschia-sdk/x/staking/types" 20 ) 21 22 func bootstrapGenesisTest(numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress) { 23 _, app, ctx := getBaseSimappWithCustomKeeper() 24 25 addrDels, _ := generateAddresses(app, ctx, numAddrs, sdk.NewInt(10000)) 26 return app, ctx, addrDels 27 } 28 29 func TestInitGenesis(t *testing.T) { 30 app, ctx, addrs := bootstrapGenesisTest(10) 31 32 valTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1) 33 34 params := app.StakingKeeper.GetParams(ctx) 35 validators := app.StakingKeeper.GetAllValidators(ctx) 36 var delegations []types.Delegation 37 38 pk0, err := codectypes.NewAnyWithValue(PKs[0]) 39 require.NoError(t, err) 40 41 pk1, err := codectypes.NewAnyWithValue(PKs[1]) 42 require.NoError(t, err) 43 44 // initialize the validators 45 bondedVal1 := types.Validator{ 46 OperatorAddress: sdk.ValAddress(addrs[0]).String(), 47 ConsensusPubkey: pk0, 48 Status: types.Bonded, 49 Tokens: valTokens, 50 DelegatorShares: valTokens.ToDec(), 51 Description: types.NewDescription("hoop", "", "", "", ""), 52 } 53 bondedVal2 := types.Validator{ 54 OperatorAddress: sdk.ValAddress(addrs[1]).String(), 55 ConsensusPubkey: pk1, 56 Status: types.Bonded, 57 Tokens: valTokens, 58 DelegatorShares: valTokens.ToDec(), 59 Description: types.NewDescription("bloop", "", "", "", ""), 60 } 61 62 // append new bonded validators to the list 63 validators = append(validators, bondedVal1, bondedVal2) 64 log.Printf("%#v", len(validators)) 65 // mint coins in the bonded pool representing the validators coins 66 require.NoError(t, 67 simapp.FundModuleAccount( 68 app, 69 ctx, 70 types.BondedPoolName, 71 sdk.NewCoins( 72 sdk.NewCoin(params.BondDenom, valTokens.MulRaw((int64)(len(validators)))), 73 ), 74 ), 75 ) 76 genesisState := types.NewGenesisState(params, validators, delegations) 77 vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, genesisState) 78 79 actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper) 80 require.Equal(t, genesisState.Params, actualGenesis.Params) 81 require.Equal(t, genesisState.Delegations, actualGenesis.Delegations) 82 require.EqualValues(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators) 83 84 // Ensure validators have addresses. 85 vals2, err := staking.WriteValidators(ctx, app.StakingKeeper) 86 require.NoError(t, err) 87 for _, val := range vals2 { 88 require.NotEmpty(t, val.Address) 89 } 90 91 // now make sure the validators are bonded and intra-tx counters are correct 92 resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0])) 93 require.True(t, found) 94 require.Equal(t, types.Bonded, resVal.Status) 95 96 resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1])) 97 require.True(t, found) 98 require.Equal(t, types.Bonded, resVal.Status) 99 100 abcivals := make([]abci.ValidatorUpdate, len(vals)) 101 for i, val := range validators { 102 abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)) 103 } 104 105 require.Equal(t, abcivals, vals) 106 } 107 108 func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) { 109 app := simapp.Setup(false) 110 ctx := app.NewContext(false, tmproto.Header{}) 111 112 consPub, err := codectypes.NewAnyWithValue(PKs[0]) 113 require.NoError(t, err) 114 115 // create mock validator 116 validator := types.Validator{ 117 OperatorAddress: sdk.ValAddress("12345678901234567890").String(), 118 ConsensusPubkey: consPub, 119 Jailed: false, 120 Tokens: sdk.NewInt(10), 121 DelegatorShares: sdk.NewInt(10).ToDec(), 122 Description: types.NewDescription("bloop", "", "", "", ""), 123 } 124 // valid params 125 params := types.Params{ 126 UnbondingTime: 10000, 127 MaxValidators: 1, 128 MaxEntries: 10, 129 BondDenom: "stake", 130 } 131 132 // test 133 134 require.Panics(t, func() { 135 // setting validator status to bonded so the balance counts towards bonded pool 136 validator.Status = types.Bonded 137 staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, &types.GenesisState{ 138 Params: params, 139 Validators: []types.Validator{validator}, 140 }) 141 }, "should panic because bonded pool balance is different from bonded pool coins") 142 143 require.Panics(t, func() { 144 // setting validator status to unbonded so the balance counts towards not bonded pool 145 validator.Status = types.Unbonded 146 staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, &types.GenesisState{ 147 Params: params, 148 Validators: []types.Validator{validator}, 149 }) 150 }, "should panic because not bonded pool balance is different from not bonded pool coins") 151 } 152 153 func TestInitGenesisLargeValidatorSet(t *testing.T) { 154 size := 200 155 require.True(t, size > 100) 156 157 app, ctx, addrs := bootstrapGenesisTest(200) 158 159 params := app.StakingKeeper.GetParams(ctx) 160 delegations := []types.Delegation{} 161 validators := make([]types.Validator, size) 162 var err error 163 164 bondedPoolAmt := sdk.ZeroInt() 165 for i := range validators { 166 validators[i], err = types.NewValidator(sdk.ValAddress(addrs[i]), 167 PKs[i], types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", "")) 168 require.NoError(t, err) 169 validators[i].Status = types.Bonded 170 171 tokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 1) 172 if i < 100 { 173 tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 2) 174 } 175 validators[i].Tokens = tokens 176 validators[i].DelegatorShares = tokens.ToDec() 177 // add bonded coins 178 bondedPoolAmt = bondedPoolAmt.Add(tokens) 179 } 180 181 genesisState := types.NewGenesisState(params, validators, delegations) 182 183 // mint coins in the bonded pool representing the validators coins 184 require.NoError(t, 185 simapp.FundModuleAccount( 186 app, 187 ctx, 188 types.BondedPoolName, 189 sdk.NewCoins(sdk.NewCoin(params.BondDenom, bondedPoolAmt)), 190 ), 191 ) 192 193 vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, genesisState) 194 195 abcivals := make([]abci.ValidatorUpdate, 100) 196 for i, val := range validators[:100] { 197 abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)) 198 } 199 200 require.Equal(t, abcivals, vals) 201 } 202 203 func TestValidateGenesis(t *testing.T) { 204 genValidators1 := make([]types.Validator, 1, 5) 205 pk := ed25519.GenPrivKey().PubKey() 206 genValidators1[0] = teststaking.NewValidator(t, sdk.ValAddress(pk.Address()), pk) 207 genValidators1[0].Tokens = sdk.OneInt() 208 genValidators1[0].DelegatorShares = sdk.OneDec() 209 210 tests := []struct { 211 name string 212 mutate func(*types.GenesisState) 213 wantErr bool 214 }{ 215 {"default", func(*types.GenesisState) {}, false}, 216 // validate genesis validators 217 {"duplicate validator", func(data *types.GenesisState) { 218 data.Validators = genValidators1 219 data.Validators = append(data.Validators, genValidators1[0]) 220 }, true}, 221 {"no delegator shares", func(data *types.GenesisState) { 222 data.Validators = genValidators1 223 data.Validators[0].DelegatorShares = sdk.ZeroDec() 224 }, true}, 225 {"jailed and bonded validator", func(data *types.GenesisState) { 226 data.Validators = genValidators1 227 data.Validators[0].Jailed = true 228 data.Validators[0].Status = types.Bonded 229 }, true}, 230 } 231 232 for _, tt := range tests { 233 tt := tt 234 t.Run(tt.name, func(t *testing.T) { 235 genesisState := types.DefaultGenesisState() 236 tt.mutate(genesisState) 237 if tt.wantErr { 238 assert.Error(t, staking.ValidateGenesis(genesisState)) 239 } else { 240 assert.NoError(t, staking.ValidateGenesis(genesisState)) 241 } 242 }) 243 } 244 }