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  }