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 }