github.com/Finschia/finschia-sdk@v0.48.1/x/staking/keeper/historical_info_test.go (about) 1 package keeper_test 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 8 9 "github.com/Finschia/finschia-sdk/simapp" 10 sdk "github.com/Finschia/finschia-sdk/types" 11 "github.com/Finschia/finschia-sdk/x/staking/teststaking" 12 "github.com/Finschia/finschia-sdk/x/staking/types" 13 ) 14 15 // IsValSetSorted reports whether valset is sorted. 16 func IsValSetSorted(data []types.Validator, powerReduction sdk.Int) bool { 17 n := len(data) 18 for i := n - 1; i > 0; i-- { 19 if types.ValidatorsByVotingPower(data).Less(i, i-1, powerReduction) { 20 return false 21 } 22 } 23 return true 24 } 25 26 func TestHistoricalInfo(t *testing.T) { 27 _, app, ctx := createTestInput() 28 29 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) 30 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 31 32 validators := make([]types.Validator, len(addrVals)) 33 34 for i, valAddr := range addrVals { 35 validators[i] = teststaking.NewValidator(t, valAddr, PKs[i]) 36 } 37 38 hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators, app.StakingKeeper.PowerReduction(ctx)) 39 app.StakingKeeper.SetHistoricalInfo(ctx, 2, &hi) 40 41 recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 2) 42 require.True(t, found, "HistoricalInfo not found after set") 43 require.Equal(t, hi, recv, "HistoricalInfo not equal") 44 require.True(t, IsValSetSorted(recv.Valset, app.StakingKeeper.PowerReduction(ctx)), "HistoricalInfo validators is not sorted") 45 46 app.StakingKeeper.DeleteHistoricalInfo(ctx, 2) 47 48 recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 2) 49 require.False(t, found, "HistoricalInfo found after delete") 50 require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty") 51 } 52 53 func TestTrackHistoricalInfo(t *testing.T) { 54 _, app, ctx := createTestInput() 55 56 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) 57 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 58 59 // set historical entries in params to 5 60 params := types.DefaultParams() 61 params.HistoricalEntries = 5 62 app.StakingKeeper.SetParams(ctx, params) 63 64 // set historical info at 5, 4 which should be pruned 65 // and check that it has been stored 66 h4 := tmproto.Header{ 67 ChainID: "HelloChain", 68 Height: 4, 69 } 70 h5 := tmproto.Header{ 71 ChainID: "HelloChain", 72 Height: 5, 73 } 74 valSet := []types.Validator{ 75 teststaking.NewValidator(t, addrVals[0], PKs[0]), 76 teststaking.NewValidator(t, addrVals[1], PKs[1]), 77 } 78 hi4 := types.NewHistoricalInfo(h4, valSet, app.StakingKeeper.PowerReduction(ctx)) 79 hi5 := types.NewHistoricalInfo(h5, valSet, app.StakingKeeper.PowerReduction(ctx)) 80 app.StakingKeeper.SetHistoricalInfo(ctx, 4, &hi4) 81 app.StakingKeeper.SetHistoricalInfo(ctx, 5, &hi5) 82 recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 4) 83 require.True(t, found) 84 require.Equal(t, hi4, recv) 85 recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5) 86 require.True(t, found) 87 require.Equal(t, hi5, recv) 88 89 // Set bonded validators in keeper 90 val1 := teststaking.NewValidator(t, addrVals[2], PKs[2]) 91 val1.Status = types.Bonded // when not bonded, consensus power is Zero 92 val1.Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 10) 93 app.StakingKeeper.SetValidator(ctx, val1) 94 app.StakingKeeper.SetLastValidatorPower(ctx, val1.GetOperator(), 10) 95 val2 := teststaking.NewValidator(t, addrVals[3], PKs[3]) 96 val1.Status = types.Bonded 97 val2.Tokens = app.StakingKeeper.TokensFromConsensusPower(ctx, 80) 98 app.StakingKeeper.SetValidator(ctx, val2) 99 app.StakingKeeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80) 100 101 vals := []types.Validator{val1, val2} 102 IsValSetSorted(vals, app.StakingKeeper.PowerReduction(ctx)) 103 104 // Set Header for BeginBlock context 105 header := tmproto.Header{ 106 ChainID: "HelloChain", 107 Height: 10, 108 } 109 ctx = ctx.WithBlockHeader(header) 110 111 app.StakingKeeper.TrackHistoricalInfo(ctx) 112 113 // Check HistoricalInfo at height 10 is persisted 114 expected := types.HistoricalInfo{ 115 Header: header, 116 Valset: vals, 117 } 118 recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10) 119 require.True(t, found, "GetHistoricalInfo failed after BeginBlock") 120 require.Equal(t, expected, recv, "GetHistoricalInfo returned unexpected result") 121 122 // Check HistoricalInfo at height 5, 4 is pruned 123 recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 4) 124 require.False(t, found, "GetHistoricalInfo did not prune earlier height") 125 require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune") 126 recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5) 127 require.False(t, found, "GetHistoricalInfo did not prune first prune height") 128 require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") 129 } 130 131 func TestGetAllHistoricalInfo(t *testing.T) { 132 _, app, ctx := createTestInput() 133 134 addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) 135 addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 136 137 valSet := []types.Validator{ 138 teststaking.NewValidator(t, addrVals[0], PKs[0]), 139 teststaking.NewValidator(t, addrVals[1], PKs[1]), 140 } 141 142 header1 := tmproto.Header{ChainID: "HelloChain", Height: 10} 143 header2 := tmproto.Header{ChainID: "HelloChain", Height: 11} 144 header3 := tmproto.Header{ChainID: "HelloChain", Height: 12} 145 146 hist1 := types.HistoricalInfo{Header: header1, Valset: valSet} 147 hist2 := types.HistoricalInfo{Header: header2, Valset: valSet} 148 hist3 := types.HistoricalInfo{Header: header3, Valset: valSet} 149 150 expHistInfos := []types.HistoricalInfo{hist1, hist2, hist3} 151 152 for i, hi := range expHistInfos { 153 app.StakingKeeper.SetHistoricalInfo(ctx, int64(10+i), &hi) 154 } 155 156 infos := app.StakingKeeper.GetAllHistoricalInfo(ctx) 157 require.Equal(t, expHistInfos, infos) 158 }