github.com/lino-network/lino@v0.6.11/x/auth/ante_test.go (about)

     1  //nolint:unused,deadcode
     2  package auth
     3  
     4  import (
     5  	"encoding/json"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/cosmos/cosmos-sdk/store"
    10  	sdk "github.com/cosmos/cosmos-sdk/types"
    11  	"github.com/cosmos/cosmos-sdk/x/auth"
    12  	"github.com/stretchr/testify/mock"
    13  	"github.com/stretchr/testify/suite"
    14  	abci "github.com/tendermint/tendermint/abci/types"
    15  	crypto "github.com/tendermint/tendermint/crypto"
    16  	"github.com/tendermint/tendermint/crypto/secp256k1"
    17  	"github.com/tendermint/tendermint/libs/log"
    18  	dbm "github.com/tendermint/tm-db"
    19  
    20  	"github.com/lino-network/lino/param"
    21  	"github.com/lino-network/lino/types"
    22  	acc "github.com/lino-network/lino/x/account"
    23  	accmn "github.com/lino-network/lino/x/account/manager"
    24  	accmodel "github.com/lino-network/lino/x/account/model"
    25  	acctypes "github.com/lino-network/lino/x/account/types"
    26  	bandwidthmock "github.com/lino-network/lino/x/bandwidth/mocks"
    27  )
    28  
    29  type TestMsg struct {
    30  	Signers    []types.AccountKey
    31  	Permission types.Permission
    32  	Amount     types.Coin
    33  }
    34  
    35  var _ types.Msg = TestMsg{}
    36  
    37  func (msg TestMsg) Route() string                   { return "normal msg" }
    38  func (msg TestMsg) Type() string                    { return "normal msg" }
    39  func (msg TestMsg) GetPermission() types.Permission { return msg.Permission }
    40  func (msg TestMsg) GetSignBytes() []byte {
    41  	bz, err := json.Marshal(msg.Signers)
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  	return bz
    46  }
    47  func (msg TestMsg) ValidateBasic() sdk.Error { return nil }
    48  func (msg TestMsg) GetSigners() []sdk.AccAddress {
    49  	addrs := make([]sdk.AccAddress, len(msg.Signers))
    50  	for i, signer := range msg.Signers {
    51  		addrs[i] = sdk.AccAddress(signer)
    52  	}
    53  	return addrs
    54  }
    55  func (msg TestMsg) GetConsumeAmount() types.Coin {
    56  	return msg.Amount
    57  }
    58  
    59  func newTestMsg(accKeys ...types.AccountKey) TestMsg {
    60  	return TestMsg{
    61  		Signers:    accKeys,
    62  		Permission: types.TransactionPermission,
    63  		Amount:     types.NewCoinFromInt64(10),
    64  	}
    65  }
    66  
    67  func newTestTx(
    68  	ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, seqs []uint64) sdk.Tx {
    69  	sigs := make([]auth.StdSignature, len(privs))
    70  
    71  	for i, priv := range privs {
    72  		signBytes := auth.StdSignBytes(
    73  			ctx.ChainID(), 0, seqs[i],
    74  			auth.StdFee{
    75  				Amount: sdk.NewCoins(sdk.NewCoin(types.LinoCoinDenom, sdk.NewInt(10000000))),
    76  			},
    77  			msgs, "")
    78  		bz, _ := priv.Sign(signBytes)
    79  		sigs[i] = auth.StdSignature{
    80  			PubKey: priv.PubKey(), Signature: bz}
    81  	}
    82  	tx := auth.NewStdTx(
    83  		msgs,
    84  		auth.StdFee{
    85  			Amount: sdk.NewCoins(sdk.NewCoin(types.LinoCoinDenom, sdk.NewInt(10000000))),
    86  		}, sigs, "")
    87  	return tx
    88  }
    89  
    90  type AnteTestSuite struct {
    91  	suite.Suite
    92  	am   acc.AccountKeeper
    93  	ph   param.ParamHolder
    94  	ctx  sdk.Context
    95  	ante sdk.AnteHandler
    96  }
    97  
    98  func (suite *AnteTestSuite) SetupTest() {
    99  	TestAccountKVStoreKey := sdk.NewKVStoreKey("account")
   100  	TestPostKVStoreKey := sdk.NewKVStoreKey("post")
   101  	TestGlobalKVStoreKey := sdk.NewKVStoreKey("global")
   102  	TestParamKVStoreKey := sdk.NewKVStoreKey("param")
   103  	TestDeveloperKVStoreKey := sdk.NewKVStoreKey("dev")
   104  	TestBandwidthKVStoreKey := sdk.NewKVStoreKey("bandwidth")
   105  	TestVoteKVStoreKey := sdk.NewKVStoreKey("vote")
   106  	TestPriceKVStoreKey := sdk.NewKVStoreKey("price")
   107  	TestValidatorKVStoreKey := sdk.NewKVStoreKey("validator")
   108  
   109  	db := dbm.NewMemDB()
   110  	ms := store.NewCommitMultiStore(db)
   111  	ms.MountStoreWithDB(TestAccountKVStoreKey, sdk.StoreTypeIAVL, db)
   112  	ms.MountStoreWithDB(TestPostKVStoreKey, sdk.StoreTypeIAVL, db)
   113  	ms.MountStoreWithDB(TestGlobalKVStoreKey, sdk.StoreTypeIAVL, db)
   114  	ms.MountStoreWithDB(TestDeveloperKVStoreKey, sdk.StoreTypeIAVL, db)
   115  	ms.MountStoreWithDB(TestBandwidthKVStoreKey, sdk.StoreTypeIAVL, db)
   116  	ms.MountStoreWithDB(TestParamKVStoreKey, sdk.StoreTypeIAVL, db)
   117  	ms.MountStoreWithDB(TestVoteKVStoreKey, sdk.StoreTypeIAVL, db)
   118  	ms.MountStoreWithDB(TestPriceKVStoreKey, sdk.StoreTypeIAVL, db)
   119  	ms.MountStoreWithDB(TestValidatorKVStoreKey, sdk.StoreTypeIAVL, db)
   120  
   121  	err := ms.LoadLatestVersion()
   122  	if err != nil {
   123  		panic(err)
   124  	}
   125  	ctx := sdk.NewContext(
   126  		ms, abci.Header{ChainID: "Lino", Height: 1, Time: time.Unix(0, 0)}, false, log.NewNopLogger())
   127  
   128  	ph := param.NewParamHolder(TestParamKVStoreKey)
   129  	err = ph.InitParam(ctx)
   130  	if err != nil {
   131  		panic(err)
   132  	}
   133  	am := accmn.NewAccountManager(TestAccountKVStoreKey, ph)
   134  	am.InitGenesis(ctx, types.MustLinoToCoin("10000000000"), []accmodel.Pool{
   135  		{
   136  			Name:    types.AccountVestingPool,
   137  			Balance: types.MustLinoToCoin("10000000000"),
   138  		},
   139  	})
   140  
   141  	bm := &bandwidthmock.BandwidthKeeper{}
   142  	bm.On("CheckBandwidth", mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe()
   143  	anteHandler := NewAnteHandler(am, bm)
   144  
   145  	suite.am = am
   146  	suite.ph = ph
   147  	suite.ctx = ctx
   148  	suite.ante = anteHandler
   149  }
   150  
   151  func (suite *AnteTestSuite) createTestAccount(username string) (secp256k1.PrivKeySecp256k1, secp256k1.PrivKeySecp256k1, types.AccountKey) {
   152  	signingKey := secp256k1.GenPrivKey()
   153  	transactionKey := secp256k1.GenPrivKey()
   154  	accParams := suite.ph.GetAccountParam(suite.ctx)
   155  	err := suite.am.GenesisAccount(suite.ctx, types.AccountKey(username),
   156  		signingKey.PubKey(), transactionKey.PubKey())
   157  	if err != nil {
   158  		panic(err)
   159  	}
   160  	err = suite.am.MoveFromPool(suite.ctx,
   161  		types.AccountVestingPool,
   162  		types.NewAccOrAddrFromAcc(types.AccountKey(username)), accParams.RegisterFee)
   163  	if err != nil {
   164  		panic(err)
   165  	}
   166  	return signingKey, transactionKey, types.AccountKey(username)
   167  }
   168  
   169  // run the tx through the anteHandler and ensure its valid
   170  func (suite *AnteTestSuite) checkValidTx(tx sdk.Tx) {
   171  	_, result, abort := suite.ante(suite.ctx, tx, false)
   172  	suite.Assert().False(abort)
   173  	suite.Assert().True(result.Code.IsOK()) // redundant
   174  	suite.Assert().True(result.IsOK())
   175  }
   176  
   177  // run the tx through the anteHandler and ensure it fails with the given code
   178  func (suite *AnteTestSuite) checkInvalidTx(tx sdk.Tx, result sdk.Result) {
   179  	_, r, abort := suite.ante(suite.ctx, tx, false)
   180  
   181  	suite.Assert().True(abort)
   182  	suite.Assert().Equal(result, r)
   183  }
   184  
   185  // Test various error cases in the AnteHandler control flow.
   186  func (suite *AnteTestSuite) TestAnteHandlerSigErrors() {
   187  	// get private key and username
   188  	_, transaction1, user1 := suite.createTestAccount("user1")
   189  	_, transaction2, user2 := suite.createTestAccount("user2")
   190  
   191  	// msg and signatures
   192  	var tx sdk.Tx
   193  	msg := newTestMsg(user1, user2)
   194  
   195  	// test no signatures
   196  	privs, seqs := []crypto.PrivKey{}, []uint64{}
   197  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   198  	suite.checkInvalidTx(tx, ErrNoSignatures().Result())
   199  
   200  	// test num sigs less than GetSigners
   201  	privs, seqs = []crypto.PrivKey{transaction1}, []uint64{0}
   202  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   203  	suite.checkInvalidTx(tx, ErrWrongNumberOfSigners().Result())
   204  
   205  	// test sig user mismatch
   206  	privs, seqs = []crypto.PrivKey{transaction2, transaction1}, []uint64{0, 0}
   207  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   208  	suite.checkInvalidTx(tx, acctypes.ErrCheckAuthenticatePubKeyOwner(user1).Result())
   209  }
   210  
   211  // Test various error cases in the AnteHandler control flow.
   212  func (suite *AnteTestSuite) TestAnteHandlerNormalTx() {
   213  	// keys and username
   214  	_, transaction1, user1 := suite.createTestAccount("user1")
   215  	_, transaction2, _ := suite.createTestAccount("user2")
   216  
   217  	// msg and signatures
   218  	var tx sdk.Tx
   219  	msg := newTestMsg(user1)
   220  
   221  	// test valid transaction
   222  	privs, seqs := []crypto.PrivKey{transaction1}, []uint64{0}
   223  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   224  	suite.checkValidTx(tx)
   225  	addr, err := suite.am.GetAddress(suite.ctx, user1)
   226  	suite.Nil(err)
   227  
   228  	seq, err := suite.am.GetSequence(suite.ctx, addr)
   229  	suite.Nil(err)
   230  	suite.Equal(seq, uint64(1))
   231  
   232  	// test no signatures
   233  	privs, seqs = []crypto.PrivKey{}, []uint64{}
   234  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   235  	suite.checkInvalidTx(tx, ErrNoSignatures().Result())
   236  
   237  	// test wrong sequence number, now we return signature failed even it's seq number error.
   238  	privs, seqs = []crypto.PrivKey{transaction1}, []uint64{0}
   239  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   240  	suite.checkInvalidTx(tx, ErrUnverifiedBytes(
   241  		"signature verification failed, chain-id:Lino, seq:1").Result())
   242  
   243  	// test wrong priv key
   244  	privs, seqs = []crypto.PrivKey{transaction2}, []uint64{1}
   245  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   246  	suite.checkInvalidTx(tx, acctypes.ErrCheckAuthenticatePubKeyOwner(user1).Result())
   247  
   248  	// test wrong sig number
   249  	privs, seqs = []crypto.PrivKey{transaction2, transaction1}, []uint64{2, 0}
   250  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   251  	suite.checkInvalidTx(tx, ErrWrongNumberOfSigners().Result())
   252  }
   253  
   254  // TestCheckAccountSigner
   255  func (suite *AnteTestSuite) TestCheckAccountSigner() {
   256  	// keys and username
   257  	_, transaction1, user1 := suite.createTestAccount("user1")
   258  	_, transaction2, _ := suite.createTestAccount("user2")
   259  	privKey := secp256k1.GenPrivKey()
   260  	err := suite.am.MoveFromPool(
   261  		suite.ctx,
   262  		types.AccountVestingPool,
   263  		types.NewAccOrAddrFromAddr(sdk.AccAddress(privKey.PubKey().Address())),
   264  		types.NewCoinFromInt64(1000))
   265  	suite.Nil(err)
   266  
   267  	testCases := []struct {
   268  		testName         string
   269  		signer           types.AccountKey
   270  		signKey          crypto.PubKey
   271  		expectSignerAddr sdk.AccAddress
   272  		expectErr        sdk.Error
   273  	}{
   274  		{
   275  			testName:         "get signer from username",
   276  			signer:           user1,
   277  			signKey:          transaction1.PubKey(),
   278  			expectSignerAddr: sdk.AccAddress(transaction1.PubKey().Address()),
   279  			expectErr:        nil,
   280  		},
   281  		{
   282  			testName:         "no permission",
   283  			signer:           user1,
   284  			signKey:          transaction2.PubKey(),
   285  			expectSignerAddr: nil,
   286  			expectErr:        acctypes.ErrCheckAuthenticatePubKeyOwner(user1),
   287  		},
   288  	}
   289  
   290  	for _, tc := range testCases {
   291  		signerAddr, err := checkAccountSigner(
   292  			suite.ctx, suite.am, tc.signer, tc.signKey)
   293  		suite.Equal(tc.expectSignerAddr, signerAddr, "%s", tc.testName)
   294  		suite.Equal(tc.expectErr, err, "%s", tc.testName)
   295  	}
   296  }
   297  
   298  // Test address signer.
   299  func (suite *AnteTestSuite) TestCheckAddrSigner() {
   300  	// keys and username
   301  	privKey := secp256k1.GenPrivKey()
   302  	err := suite.am.MoveFromPool(suite.ctx,
   303  		types.AccountVestingPool,
   304  		types.NewAccOrAddrFromAddr(sdk.AccAddress(privKey.PubKey().Address())),
   305  		types.NewCoinFromInt64(1000))
   306  	suite.Nil(err)
   307  
   308  	newPrivKey := secp256k1.GenPrivKey()
   309  
   310  	testCases := []struct {
   311  		testName  string
   312  		signer    sdk.AccAddress
   313  		signKey   crypto.PubKey
   314  		expectErr sdk.Error
   315  		isPaid    bool
   316  	}{
   317  		{
   318  			testName:  "get signer from address",
   319  			signer:    sdk.AccAddress(privKey.PubKey().Address()),
   320  			signKey:   privKey.PubKey(),
   321  			expectErr: nil,
   322  		},
   323  		{
   324  			testName: "sign key without bank struct",
   325  			signer:   sdk.AccAddress(newPrivKey.PubKey().Address()),
   326  			signKey:  newPrivKey.PubKey(),
   327  			expectErr: acctypes.ErrAccountBankNotFound(
   328  				sdk.AccAddress(newPrivKey.PubKey().Address())),
   329  		},
   330  		{
   331  			testName:  "sign key without bank struct but paid",
   332  			signer:    sdk.AccAddress(newPrivKey.PubKey().Address()),
   333  			signKey:   newPrivKey.PubKey(),
   334  			expectErr: nil,
   335  			isPaid:    true,
   336  		},
   337  	}
   338  
   339  	for _, tc := range testCases {
   340  		err := checkAddrSigner(
   341  			suite.ctx, suite.am, tc.signer, tc.signKey, tc.isPaid)
   342  		suite.Equal(tc.expectErr, err, "%s", tc.testName)
   343  	}
   344  }
   345  
   346  // Test multi sig.
   347  func (suite *AnteTestSuite) TestMultiSig() {
   348  	// keys and username
   349  	_, transaction1, user1 := suite.createTestAccount("user1")
   350  	_, transaction2, _ := suite.createTestAccount("user2")
   351  	// _, transaction3, user3 := suite.createTestAccount("user3")
   352  
   353  	// msg and signatures
   354  	var tx sdk.Tx
   355  	msg := newTestMsg(user1, user1)
   356  
   357  	// test first private key is wrong
   358  	privs, seqs := []crypto.PrivKey{transaction2, transaction1}, []uint64{0, 1}
   359  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   360  	suite.checkInvalidTx(
   361  		tx,
   362  		acctypes.ErrCheckAuthenticatePubKeyOwner(user1).Result())
   363  
   364  	// test second private key is wrong
   365  	privs, seqs = []crypto.PrivKey{transaction1, transaction2}, []uint64{0, 1}
   366  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   367  	suite.checkInvalidTx(
   368  		tx,
   369  		acctypes.ErrCheckAuthenticatePubKeyOwner(user1).Result())
   370  
   371  	// test too many sigs
   372  	privs, seqs = []crypto.PrivKey{transaction1, transaction2, transaction1}, []uint64{0, 1, 1}
   373  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   374  	suite.checkInvalidTx(
   375  		tx,
   376  		sdk.ErrTooManySignatures("signatures: 3, limit: 2").Result())
   377  
   378  	// test valid transaction
   379  	privs, seqs = []crypto.PrivKey{transaction1, transaction1}, []uint64{1, 2}
   380  	tx = newTestTx(suite.ctx, []sdk.Msg{msg}, privs, seqs)
   381  	suite.checkValidTx(tx)
   382  }
   383  
   384  func TestAnteTestSuite(t *testing.T) {
   385  	suite.Run(t, &AnteTestSuite{})
   386  }