github.com/Finschia/finschia-sdk@v0.48.1/x/genutil/gentx_test.go (about)

     1  package genutil_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/rand"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/suite"
    11  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    12  
    13  	"github.com/Finschia/finschia-sdk/crypto/keys/secp256k1"
    14  	"github.com/Finschia/finschia-sdk/simapp"
    15  	"github.com/Finschia/finschia-sdk/simapp/helpers"
    16  	simappparams "github.com/Finschia/finschia-sdk/simapp/params"
    17  	sdk "github.com/Finschia/finschia-sdk/types"
    18  	banktypes "github.com/Finschia/finschia-sdk/x/bank/types"
    19  	"github.com/Finschia/finschia-sdk/x/genutil"
    20  	"github.com/Finschia/finschia-sdk/x/genutil/types"
    21  	"github.com/Finschia/finschia-sdk/x/staking"
    22  	stakingtypes "github.com/Finschia/finschia-sdk/x/staking/types"
    23  )
    24  
    25  var (
    26  	priv1 = secp256k1.GenPrivKey()
    27  	priv2 = secp256k1.GenPrivKey()
    28  	pk1   = priv1.PubKey()
    29  	pk2   = priv2.PubKey()
    30  	addr1 = sdk.AccAddress(pk1.Address())
    31  	addr2 = sdk.AccAddress(pk2.Address())
    32  	desc  = stakingtypes.NewDescription("testname", "", "", "", "")
    33  	comm  = stakingtypes.CommissionRates{}
    34  )
    35  
    36  // GenTxTestSuite is a test suite to be used with gentx tests.
    37  type GenTxTestSuite struct {
    38  	suite.Suite
    39  
    40  	ctx            sdk.Context
    41  	app            *simapp.SimApp
    42  	encodingConfig simappparams.EncodingConfig
    43  
    44  	msg1, msg2 *stakingtypes.MsgCreateValidator
    45  }
    46  
    47  func (suite *GenTxTestSuite) SetupTest() {
    48  	checkTx := false
    49  	app := simapp.Setup(checkTx)
    50  	suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{})
    51  	suite.app = app
    52  	suite.encodingConfig = simapp.MakeTestEncodingConfig()
    53  
    54  	var err error
    55  	amount := sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)
    56  	one := sdk.OneInt()
    57  	suite.msg1, err = stakingtypes.NewMsgCreateValidator(
    58  		sdk.ValAddress(pk1.Address()), pk1, amount, desc, comm, one)
    59  	suite.NoError(err)
    60  	suite.msg2, err = stakingtypes.NewMsgCreateValidator(
    61  		sdk.ValAddress(pk2.Address()), pk1, amount, desc, comm, one)
    62  	suite.NoError(err)
    63  }
    64  
    65  func (suite *GenTxTestSuite) setAccountBalance(addr sdk.AccAddress, amount int64) json.RawMessage {
    66  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)
    67  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
    68  
    69  	err := simapp.FundAccount(suite.app, suite.ctx, addr, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, amount)})
    70  	suite.Require().NoError(err)
    71  
    72  	bankGenesisState := suite.app.BankKeeper.ExportGenesis(suite.ctx)
    73  	bankGenesis, err := suite.encodingConfig.Amino.MarshalJSON(bankGenesisState) // TODO switch this to use Marshaler
    74  	suite.Require().NoError(err)
    75  
    76  	return bankGenesis
    77  }
    78  
    79  func (suite *GenTxTestSuite) TestSetGenTxsInAppGenesisState() {
    80  	var (
    81  		txBuilder = suite.encodingConfig.TxConfig.NewTxBuilder()
    82  		genTxs    []sdk.Tx
    83  	)
    84  
    85  	testCases := []struct {
    86  		msg      string
    87  		malleate func()
    88  		expPass  bool
    89  	}{
    90  		{
    91  			"one genesis transaction",
    92  			func() {
    93  				err := txBuilder.SetMsgs(suite.msg1)
    94  				suite.Require().NoError(err)
    95  				tx := txBuilder.GetTx()
    96  				genTxs = []sdk.Tx{tx}
    97  			},
    98  			true,
    99  		},
   100  		{
   101  			"two genesis transactions",
   102  			func() {
   103  				err := txBuilder.SetMsgs(suite.msg1, suite.msg2)
   104  				suite.Require().NoError(err)
   105  				tx := txBuilder.GetTx()
   106  				genTxs = []sdk.Tx{tx}
   107  			},
   108  			true,
   109  		},
   110  	}
   111  
   112  	for _, tc := range testCases {
   113  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   114  			suite.SetupTest()
   115  			cdc := suite.encodingConfig.Marshaler
   116  			txJSONEncoder := suite.encodingConfig.TxConfig.TxJSONEncoder()
   117  
   118  			tc.malleate()
   119  			appGenesisState, err := genutil.SetGenTxsInAppGenesisState(cdc, txJSONEncoder, make(map[string]json.RawMessage), genTxs)
   120  
   121  			if tc.expPass {
   122  				suite.Require().NoError(err)
   123  				suite.Require().NotNil(appGenesisState[types.ModuleName])
   124  
   125  				var genesisState types.GenesisState
   126  				err := cdc.UnmarshalJSON(appGenesisState[types.ModuleName], &genesisState)
   127  				suite.Require().NoError(err)
   128  				suite.Require().NotNil(genesisState.GenTxs)
   129  			} else {
   130  				suite.Require().Error(err)
   131  			}
   132  		})
   133  	}
   134  }
   135  
   136  func (suite *GenTxTestSuite) TestValidateAccountInGenesis() {
   137  	var (
   138  		appGenesisState = make(map[string]json.RawMessage)
   139  		coins           sdk.Coins
   140  	)
   141  
   142  	testCases := []struct {
   143  		msg      string
   144  		malleate func()
   145  		expPass  bool
   146  	}{
   147  		{
   148  			"no accounts",
   149  			func() {
   150  				coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}
   151  			},
   152  			false,
   153  		},
   154  		{
   155  			"account without balance in the genesis state",
   156  			func() {
   157  				coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}
   158  				appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr2, 50)
   159  			},
   160  			false,
   161  		},
   162  		{
   163  			"account without enough funds of default bond denom",
   164  			func() {
   165  				coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)}
   166  				appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr1, 25)
   167  			},
   168  			false,
   169  		},
   170  		{
   171  			"account with enough funds of default bond denom",
   172  			func() {
   173  				coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)}
   174  				appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr1, 25)
   175  			},
   176  			true,
   177  		},
   178  	}
   179  	for _, tc := range testCases {
   180  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   181  			suite.SetupTest()
   182  			cdc := suite.encodingConfig.Marshaler
   183  
   184  			suite.app.StakingKeeper.SetParams(suite.ctx, stakingtypes.DefaultParams())
   185  			stakingGenesisState := staking.ExportGenesis(suite.ctx, suite.app.StakingKeeper)
   186  			suite.Require().Equal(stakingGenesisState.Params, stakingtypes.DefaultParams())
   187  			stakingGenesis, err := cdc.MarshalJSON(stakingGenesisState) // TODO switch this to use Marshaler
   188  			suite.Require().NoError(err)
   189  			appGenesisState[stakingtypes.ModuleName] = stakingGenesis
   190  
   191  			tc.malleate()
   192  			err = genutil.ValidateAccountInGenesis(
   193  				appGenesisState, banktypes.GenesisBalancesIterator{},
   194  				addr1, coins, cdc,
   195  			)
   196  
   197  			if tc.expPass {
   198  				suite.Require().NoError(err)
   199  			} else {
   200  				suite.Require().Error(err)
   201  			}
   202  		})
   203  	}
   204  }
   205  
   206  func (suite *GenTxTestSuite) TestDeliverGenTxs() {
   207  	var (
   208  		genTxs    []json.RawMessage
   209  		txBuilder = suite.encodingConfig.TxConfig.NewTxBuilder()
   210  	)
   211  
   212  	testCases := []struct {
   213  		msg      string
   214  		malleate func()
   215  		expPass  bool
   216  	}{
   217  		{
   218  			"no signature supplied",
   219  			func() {
   220  				err := txBuilder.SetMsgs(suite.msg1)
   221  				suite.Require().NoError(err)
   222  
   223  				genTxs = make([]json.RawMessage, 1)
   224  				tx, err := suite.encodingConfig.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
   225  				suite.Require().NoError(err)
   226  				genTxs[0] = tx
   227  			},
   228  			false,
   229  		},
   230  		{
   231  			"success",
   232  			func() {
   233  				_ = suite.setAccountBalance(addr1, 50)
   234  				_ = suite.setAccountBalance(addr2, 1)
   235  
   236  				msg := banktypes.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)})
   237  				tx, err := helpers.GenSignedMockTx(
   238  					rand.New(rand.NewSource(time.Now().UnixNano())),
   239  					suite.encodingConfig.TxConfig,
   240  					[]sdk.Msg{msg},
   241  					sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)},
   242  					helpers.DefaultGenTxGas,
   243  					suite.ctx.ChainID(),
   244  					[]uint64{0},
   245  					[]uint64{0},
   246  					priv1,
   247  				)
   248  				suite.Require().NoError(err)
   249  
   250  				genTxs = make([]json.RawMessage, 1)
   251  				genTx, err := suite.encodingConfig.TxConfig.TxJSONEncoder()(tx)
   252  				suite.Require().NoError(err)
   253  				genTxs[0] = genTx
   254  			},
   255  			true,
   256  		},
   257  	}
   258  
   259  	for _, tc := range testCases {
   260  		suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
   261  			suite.SetupTest()
   262  
   263  			tc.malleate()
   264  
   265  			if tc.expPass {
   266  				suite.Require().NotPanics(func() {
   267  					genutil.DeliverGenTxs(
   268  						suite.ctx, genTxs, suite.app.StakingKeeper, suite.app.BaseApp.DeliverTx,
   269  						suite.encodingConfig.TxConfig,
   270  					)
   271  				})
   272  			} else {
   273  				suite.Require().Panics(func() {
   274  					genutil.DeliverGenTxs(
   275  						suite.ctx, genTxs, suite.app.StakingKeeper, suite.app.BaseApp.DeliverTx,
   276  						suite.encodingConfig.TxConfig,
   277  					)
   278  				})
   279  			}
   280  		})
   281  	}
   282  }
   283  
   284  func TestGenTxTestSuite(t *testing.T) {
   285  	suite.Run(t, new(GenTxTestSuite))
   286  }