github.com/Finschia/finschia-sdk@v0.49.1/x/slashing/simulation/operations_test.go (about)

     1  package simulation_test
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  	"time"
     7  
     8  	ocabci "github.com/Finschia/ostracon/abci/types"
     9  	"github.com/stretchr/testify/require"
    10  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    11  
    12  	"github.com/Finschia/finschia-sdk/simapp"
    13  	simappparams "github.com/Finschia/finschia-sdk/simapp/params"
    14  	sdk "github.com/Finschia/finschia-sdk/types"
    15  	simtypes "github.com/Finschia/finschia-sdk/types/simulation"
    16  	distrtypes "github.com/Finschia/finschia-sdk/x/distribution/types"
    17  	minttypes "github.com/Finschia/finschia-sdk/x/mint/types"
    18  	"github.com/Finschia/finschia-sdk/x/slashing/simulation"
    19  	"github.com/Finschia/finschia-sdk/x/slashing/types"
    20  	stakingtypes "github.com/Finschia/finschia-sdk/x/staking/types"
    21  )
    22  
    23  // TestWeightedOperations tests the weights of the operations.
    24  func TestWeightedOperations(t *testing.T) {
    25  	app, ctx := createTestApp(false)
    26  	ctx.WithChainID("test-chain")
    27  
    28  	cdc := app.AppCodec()
    29  	appParams := make(simtypes.AppParams)
    30  
    31  	s := rand.NewSource(1)
    32  	r := rand.New(s)
    33  	accs := simtypes.RandomAccounts(r, 3)
    34  
    35  	expected := []struct {
    36  		weight     int
    37  		opMsgRoute string
    38  		opMsgName  string
    39  	}{{simappparams.DefaultWeightMsgUnjail, types.ModuleName, types.TypeMsgUnjail}}
    40  
    41  	weightesOps := simulation.WeightedOperations(appParams, cdc, app.AccountKeeper, app.BankKeeper, app.SlashingKeeper, app.StakingKeeper)
    42  	for i, w := range weightesOps {
    43  		operationMsg, _, _ := w.Op()(r, app.BaseApp, ctx, accs, ctx.ChainID())
    44  		// the following checks are very much dependent from the ordering of the output given
    45  		// by WeightedOperations. if the ordering in WeightedOperations changes some tests
    46  		// will fail
    47  		require.Equal(t, expected[i].weight, w.Weight(), "weight should be the same")
    48  		require.Equal(t, expected[i].opMsgRoute, operationMsg.Route, "route should be the same")
    49  		require.Equal(t, expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same")
    50  	}
    51  }
    52  
    53  // TestSimulateMsgUnjail tests the normal scenario of a valid message of type types.MsgUnjail.
    54  // Abonormal scenarios, where the message is created by an errors, are not tested here.
    55  func TestSimulateMsgUnjail(t *testing.T) {
    56  	app, ctx := createTestApp(false)
    57  	blockTime := time.Now().UTC()
    58  	ctx = ctx.WithBlockTime(blockTime)
    59  
    60  	// setup 3 accounts
    61  	s := rand.NewSource(1)
    62  	r := rand.New(s)
    63  	accounts := getTestingAccounts(t, r, app, ctx, 3)
    64  
    65  	// setup accounts[0] as validator0
    66  	validator0 := getTestingValidator0(t, app, ctx, accounts)
    67  
    68  	// setup validator0 by consensus address
    69  	err := app.StakingKeeper.SetValidatorByConsAddr(ctx, validator0)
    70  	require.NoError(t, err)
    71  	val0ConsAddress, err := validator0.GetConsAddr()
    72  	require.NoError(t, err)
    73  	info := types.NewValidatorSigningInfo(val0ConsAddress, int64(4), int64(3),
    74  		time.Unix(2, 0), false, int64(10))
    75  	app.SlashingKeeper.SetValidatorSigningInfo(ctx, val0ConsAddress, info)
    76  
    77  	// put validator0 in jail
    78  	app.StakingKeeper.Jail(ctx, val0ConsAddress)
    79  
    80  	// setup self delegation
    81  	delTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
    82  	validator0, issuedShares := validator0.AddTokensFromDel(delTokens)
    83  	val0AccAddress, err := sdk.ValAddressFromBech32(validator0.OperatorAddress)
    84  	require.NoError(t, err)
    85  	selfDelegation := stakingtypes.NewDelegation(val0AccAddress.Bytes(), validator0.GetOperator(), issuedShares)
    86  	app.StakingKeeper.SetDelegation(ctx, selfDelegation)
    87  	app.DistrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), val0AccAddress.Bytes(), distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200))
    88  
    89  	// begin a new block
    90  	app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}})
    91  
    92  	// execute operation
    93  	op := simulation.SimulateMsgUnjail(app.AccountKeeper, app.BankKeeper, app.SlashingKeeper, app.StakingKeeper)
    94  	operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "")
    95  	require.NoError(t, err)
    96  
    97  	var msg types.MsgUnjail
    98  	err = types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg)
    99  	require.NoError(t, err)
   100  
   101  	require.True(t, operationMsg.OK)
   102  	require.Equal(t, types.TypeMsgUnjail, msg.Type())
   103  	require.Equal(t, "linkvaloper1tnh2q55v8wyygtt9srz5safamzdengsn8rx882", msg.ValidatorAddr)
   104  	require.Len(t, futureOperations, 0)
   105  }
   106  
   107  // returns context and an app with updated mint keeper
   108  func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) {
   109  	app := simapp.Setup(isCheckTx)
   110  
   111  	ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{})
   112  	app.MintKeeper.SetParams(ctx, minttypes.DefaultParams())
   113  	app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter())
   114  
   115  	return app, ctx
   116  }
   117  
   118  func getTestingAccounts(t *testing.T, r *rand.Rand, app *simapp.SimApp, ctx sdk.Context, n int) []simtypes.Account {
   119  	t.Helper()
   120  	accounts := simtypes.RandomAccounts(r, n)
   121  
   122  	initAmt := app.StakingKeeper.TokensFromConsensusPower(ctx, 200)
   123  	initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt))
   124  
   125  	// add coins to the accounts
   126  	for _, account := range accounts {
   127  		acc := app.AccountKeeper.NewAccountWithAddress(ctx, account.Address)
   128  		app.AccountKeeper.SetAccount(ctx, acc)
   129  		require.NoError(t, simapp.FundAccount(app, ctx, account.Address, initCoins))
   130  	}
   131  
   132  	return accounts
   133  }
   134  
   135  func getTestingValidator0(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account) stakingtypes.Validator {
   136  	t.Helper()
   137  	commission0 := stakingtypes.NewCommission(sdk.ZeroDec(), sdk.OneDec(), sdk.OneDec())
   138  	return getTestingValidator(t, app, ctx, accounts, commission0, 0)
   139  }
   140  
   141  func getTestingValidator(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account, commission stakingtypes.Commission, n int) stakingtypes.Validator {
   142  	t.Helper()
   143  	account := accounts[n]
   144  	valPubKey := account.ConsKey.PubKey()
   145  	valAddr := sdk.ValAddress(account.PubKey.Address().Bytes())
   146  	validator, err := stakingtypes.NewValidator(valAddr, valPubKey, stakingtypes.Description{})
   147  	require.NoError(t, err)
   148  	validator, err = validator.SetInitialCommission(commission)
   149  	require.NoError(t, err)
   150  
   151  	validator.DelegatorShares = sdk.NewDec(100)
   152  	validator.Tokens = sdk.NewInt(1000000)
   153  
   154  	app.StakingKeeper.SetValidator(ctx, validator)
   155  
   156  	return validator
   157  }