github.com/Finschia/finschia-sdk@v0.49.1/x/auth/ante/sigverify_test.go (about) 1 package ante_test 2 3 import ( 4 "fmt" 5 6 "github.com/Finschia/finschia-sdk/client" 7 "github.com/Finschia/finschia-sdk/codec" 8 "github.com/Finschia/finschia-sdk/crypto/keys/ed25519" 9 kmultisig "github.com/Finschia/finschia-sdk/crypto/keys/multisig" 10 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 11 "github.com/Finschia/finschia-sdk/crypto/keys/secp256r1" 12 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 13 "github.com/Finschia/finschia-sdk/crypto/types/multisig" 14 "github.com/Finschia/finschia-sdk/simapp" 15 "github.com/Finschia/finschia-sdk/testutil/testdata" 16 sdk "github.com/Finschia/finschia-sdk/types" 17 "github.com/Finschia/finschia-sdk/types/tx/signing" 18 "github.com/Finschia/finschia-sdk/x/auth/ante" 19 "github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx" 20 "github.com/Finschia/finschia-sdk/x/auth/types" 21 ) 22 23 func (suite *AnteTestSuite) TestSetPubKey() { 24 suite.SetupTest(true) // setup 25 require := suite.Require() 26 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() 27 28 // keys and addresses 29 priv1, pub1, addr1 := testdata.KeyTestPubAddr() 30 priv2, pub2, addr2 := testdata.KeyTestPubAddr() 31 priv3, pub3, addr3 := testdata.KeyTestPubAddrSecp256R1(require) 32 33 addrs := []sdk.AccAddress{addr1, addr2, addr3} 34 pubs := []cryptotypes.PubKey{pub1, pub2, pub3} 35 36 msgs := make([]sdk.Msg, len(addrs)) 37 // set accounts and create msg for each address 38 for i, addr := range addrs { 39 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 40 require.NoError(acc.SetAccountNumber(uint64(i))) 41 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 42 msgs[i] = testdata.NewTestMsg(addr) 43 } 44 require.NoError(suite.txBuilder.SetMsgs(msgs...)) 45 suite.txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) 46 suite.txBuilder.SetGasLimit(testdata.NewTestGasLimit()) 47 48 privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0} 49 tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) 50 require.NoError(err) 51 52 spkd := ante.NewSetPubKeyDecorator(suite.app.AccountKeeper) 53 antehandler := sdk.ChainAnteDecorators(spkd) 54 55 ctx, err := antehandler(suite.ctx, tx, false) 56 require.NoError(err) 57 58 // Require that all accounts have pubkey set after Decorator runs 59 for i, addr := range addrs { 60 pk, err := suite.app.AccountKeeper.GetPubKey(ctx, addr) 61 require.NoError(err, "Error on retrieving pubkey from account") 62 require.True(pubs[i].Equals(pk), 63 "Wrong Pubkey retrieved from AccountKeeper, idx=%d\nexpected=%s\n got=%s", i, pubs[i], pk) 64 } 65 } 66 67 func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() { 68 params := types.DefaultParams() 69 msg := []byte{1, 2, 3, 4} 70 cdc := simapp.MakeTestEncodingConfig().Amino 71 72 p := types.DefaultParams() 73 skR1, _ := secp256r1.GenPrivKey() 74 pkSet1, sigSet1 := generatePubKeysAndSignatures(5, msg, false) 75 multisigKey1 := kmultisig.NewLegacyAminoPubKey(2, pkSet1) 76 multisignature1 := multisig.NewMultisig(len(pkSet1)) 77 expectedCost1 := expectedGasCostByKeys(pkSet1) 78 for i := 0; i < len(pkSet1); i++ { 79 stdSig := legacytx.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]} //nolint:staticcheck // this will be removed when proto is ready 80 sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig) 81 suite.Require().NoError(err) 82 err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1) 83 suite.Require().NoError(err) 84 } 85 86 type args struct { 87 meter sdk.GasMeter 88 sig signing.SignatureData 89 pubkey cryptotypes.PubKey 90 params types.Params 91 } 92 tests := []struct { 93 name string 94 args args 95 gasConsumed uint64 96 shouldErr bool 97 }{ 98 {"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), nil, ed25519.GenPrivKey().PubKey(), params}, p.SigVerifyCostED25519, true}, 99 {"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), nil, secp256k1.GenPrivKey().PubKey(), params}, p.SigVerifyCostSecp256k1, false}, 100 {"PubKeySecp256r1", args{sdk.NewInfiniteGasMeter(), nil, skR1.PubKey(), params}, p.SigVerifyCostSecp256r1(), false}, 101 {"Multisig", args{sdk.NewInfiniteGasMeter(), multisignature1, multisigKey1, params}, expectedCost1, false}, 102 {"unknown key", args{sdk.NewInfiniteGasMeter(), nil, nil, params}, 0, true}, 103 } 104 for _, tt := range tests { 105 sigV2 := signing.SignatureV2{ 106 PubKey: tt.args.pubkey, 107 Data: tt.args.sig, 108 Sequence: 0, // Arbitrary account sequence 109 } 110 err := ante.DefaultSigVerificationGasConsumer(tt.args.meter, sigV2, tt.args.params) 111 112 if tt.shouldErr { 113 suite.Require().NotNil(err) 114 } else { 115 suite.Require().Nil(err) 116 suite.Require().Equal(tt.gasConsumed, tt.args.meter.GasConsumed(), fmt.Sprintf("%d != %d", tt.gasConsumed, tt.args.meter.GasConsumed())) 117 } 118 } 119 } 120 121 func (suite *AnteTestSuite) TestSigVerification() { 122 suite.SetupTest(true) // setup 123 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() 124 125 // make block height non-zero to ensure account numbers part of signBytes 126 suite.ctx = suite.ctx.WithBlockHeight(1) 127 128 // keys and addresses 129 priv1, _, addr1 := testdata.KeyTestPubAddr() 130 priv2, _, addr2 := testdata.KeyTestPubAddr() 131 priv3, _, addr3 := testdata.KeyTestPubAddr() 132 133 addrs := []sdk.AccAddress{addr1, addr2, addr3} 134 135 msgs := make([]sdk.Msg, len(addrs)) 136 // set accounts and create msg for each address 137 for i, addr := range addrs { 138 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 139 suite.Require().NoError(acc.SetAccountNumber(uint64(i))) 140 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 141 msgs[i] = testdata.NewTestMsg(addr) 142 } 143 144 feeAmount := testdata.NewTestFeeAmount() 145 gasLimit := testdata.NewTestGasLimit() 146 147 spkd := ante.NewSetPubKeyDecorator(suite.app.AccountKeeper) 148 svd := ante.NewSigVerificationDecorator(suite.app.AccountKeeper, suite.clientCtx.TxConfig.SignModeHandler()) 149 antehandler := sdk.ChainAnteDecorators(spkd, svd) 150 151 type testCase struct { 152 name string 153 privs []cryptotypes.PrivKey 154 accNums []uint64 155 accSeqs []uint64 156 invalidSigs bool 157 recheck bool 158 shouldErr bool 159 } 160 validSigs := false 161 testCases := []testCase{ 162 {"no signers", []cryptotypes.PrivKey{}, []uint64{}, []uint64{}, validSigs, false, true}, 163 {"not enough signers", []cryptotypes.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}, validSigs, false, true}, 164 {"wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{2, 1, 0}, []uint64{0, 0, 0}, validSigs, false, true}, 165 {"wrong accnums", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, validSigs, false, true}, 166 {"wrong sequences", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{3, 4, 5}, validSigs, false, true}, 167 {"valid tx", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, validSigs, false, false}, 168 {"no err on recheck", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 0, 0}, []uint64{0, 0, 0}, !validSigs, true, false}, 169 } 170 for i, tc := range testCases { 171 suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck) 172 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test 173 174 suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) 175 suite.txBuilder.SetFeeAmount(feeAmount) 176 suite.txBuilder.SetGasLimit(gasLimit) 177 178 tx, err := suite.CreateTestTx(tc.privs, tc.accNums, tc.accSeqs, suite.ctx.ChainID()) 179 suite.Require().NoError(err) 180 if tc.invalidSigs { 181 txSigs, _ := tx.GetSignaturesV2() 182 badSig, _ := tc.privs[0].Sign([]byte("unrelated message")) 183 txSigs[0] = signing.SignatureV2{ 184 PubKey: tc.privs[0].PubKey(), 185 Data: &signing.SingleSignatureData{ 186 SignMode: suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), 187 Signature: badSig, 188 }, 189 Sequence: tc.accSeqs[0], 190 } 191 err := suite.txBuilder.SetSignatures(txSigs...) 192 suite.Require().NoError(err) 193 tx = suite.txBuilder.GetTx() 194 } 195 196 _, err = antehandler(suite.ctx, tx, false) 197 if tc.shouldErr { 198 suite.Require().NotNil(err, "TestCase %d: %s did not error as expected", i, tc.name) 199 } else { 200 suite.Require().Nil(err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) 201 } 202 } 203 } 204 205 // This test is exactly like the one above, but we set the codec explicitly to 206 // Amino. 207 // Once https://github.com/cosmos/cosmos-sdk/issues/6190 is in, we can remove 208 // this, since it'll be handled by the test matrix. 209 // In the meantime, we want to make double-sure amino compatibility works. 210 // ref: https://github.com/cosmos/cosmos-sdk/issues/7229 211 func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() { 212 suite.app, suite.ctx = createTestApp(true) 213 suite.ctx = suite.ctx.WithBlockHeight(1) 214 215 // Set up TxConfig. 216 aminoCdc := codec.NewLegacyAmino() 217 // We're using TestMsg amino encoding in some tests, so register it here. 218 txConfig := legacytx.StdTxConfig{Cdc: aminoCdc} 219 220 suite.clientCtx = client.Context{}. 221 WithTxConfig(txConfig) 222 223 anteHandler, err := ante.NewAnteHandler( 224 ante.HandlerOptions{ 225 AccountKeeper: suite.app.AccountKeeper, 226 BankKeeper: suite.app.BankKeeper, 227 FeegrantKeeper: suite.app.FeeGrantKeeper, 228 SignModeHandler: txConfig.SignModeHandler(), 229 SigGasConsumer: ante.DefaultSigVerificationGasConsumer, 230 }, 231 ) 232 233 suite.Require().NoError(err) 234 suite.anteHandler = anteHandler 235 236 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() 237 238 // make block height non-zero to ensure account numbers part of signBytes 239 suite.ctx = suite.ctx.WithBlockHeight(1) 240 241 // keys and addresses 242 priv1, _, addr1 := testdata.KeyTestPubAddr() 243 priv2, _, addr2 := testdata.KeyTestPubAddr() 244 priv3, _, addr3 := testdata.KeyTestPubAddr() 245 246 addrs := []sdk.AccAddress{addr1, addr2, addr3} 247 248 msgs := make([]sdk.Msg, len(addrs)) 249 // set accounts and create msg for each address 250 for i, addr := range addrs { 251 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 252 suite.Require().NoError(acc.SetAccountNumber(uint64(i))) 253 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 254 msgs[i] = testdata.NewTestMsg(addr) 255 } 256 257 feeAmount := testdata.NewTestFeeAmount() 258 gasLimit := testdata.NewTestGasLimit() 259 260 spkd := ante.NewSetPubKeyDecorator(suite.app.AccountKeeper) 261 svd := ante.NewSigVerificationDecorator(suite.app.AccountKeeper, suite.clientCtx.TxConfig.SignModeHandler()) 262 antehandler := sdk.ChainAnteDecorators(spkd, svd) 263 264 type testCase struct { 265 name string 266 privs []cryptotypes.PrivKey 267 accNums []uint64 268 accSeqs []uint64 269 recheck bool 270 shouldErr bool 271 } 272 testCases := []testCase{ 273 {"no signers", []cryptotypes.PrivKey{}, []uint64{}, []uint64{}, false, true}, 274 {"not enough signers", []cryptotypes.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}, false, true}, 275 {"wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{2, 1, 0}, []uint64{0, 0, 0}, false, true}, 276 {"wrong accnums", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, false, true}, 277 {"wrong sequences", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{3, 4, 5}, false, true}, 278 {"valid tx", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, false, false}, 279 {"no err on recheck", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, true, false}, 280 } 281 for i, tc := range testCases { 282 suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck) 283 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test 284 285 suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) 286 suite.txBuilder.SetFeeAmount(feeAmount) 287 suite.txBuilder.SetGasLimit(gasLimit) 288 289 tx, err := suite.CreateTestTx(tc.privs, tc.accNums, tc.accSeqs, suite.ctx.ChainID()) 290 suite.Require().NoError(err) 291 292 _, err = antehandler(suite.ctx, tx, false) 293 if tc.shouldErr { 294 suite.Require().NotNil(err, "TestCase %d: %s did not error as expected", i, tc.name) 295 } else { 296 suite.Require().Nil(err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) 297 } 298 } 299 } 300 301 func (suite *AnteTestSuite) TestSigIntegration() { 302 // generate private keys 303 privs := []cryptotypes.PrivKey{ 304 secp256k1.GenPrivKey(), 305 secp256k1.GenPrivKey(), 306 secp256k1.GenPrivKey(), 307 } 308 309 params := types.DefaultParams() 310 initialSigCost := params.SigVerifyCostSecp256k1 311 initialCost, err := suite.runSigDecorators(params, false, privs...) 312 suite.Require().Nil(err) 313 314 params.SigVerifyCostSecp256k1 *= 2 315 doubleCost, err := suite.runSigDecorators(params, false, privs...) 316 suite.Require().Nil(err) 317 318 suite.Require().Equal(initialSigCost*uint64(len(privs)), doubleCost-initialCost) 319 } 320 321 func (suite *AnteTestSuite) runSigDecorators(params types.Params, _ bool, privs ...cryptotypes.PrivKey) (sdk.Gas, error) { 322 suite.SetupTest(true) // setup 323 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() 324 325 // Make block-height non-zero to include accNum in SignBytes 326 suite.ctx = suite.ctx.WithBlockHeight(1) 327 suite.app.AccountKeeper.SetParams(suite.ctx, params) 328 329 msgs := make([]sdk.Msg, len(privs)) 330 accNums := make([]uint64, len(privs)) 331 accSeqs := make([]uint64, len(privs)) 332 // set accounts and create msg for each address 333 for i, priv := range privs { 334 addr := sdk.AccAddress(priv.PubKey().Address()) 335 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 336 suite.Require().NoError(acc.SetAccountNumber(uint64(i))) 337 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 338 msgs[i] = testdata.NewTestMsg(addr) 339 accNums[i] = uint64(i) 340 accSeqs[i] = uint64(0) 341 } 342 suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) 343 344 feeAmount := testdata.NewTestFeeAmount() 345 gasLimit := testdata.NewTestGasLimit() 346 suite.txBuilder.SetFeeAmount(feeAmount) 347 suite.txBuilder.SetGasLimit(gasLimit) 348 349 tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) 350 suite.Require().NoError(err) 351 352 spkd := ante.NewSetPubKeyDecorator(suite.app.AccountKeeper) 353 svgc := ante.NewSigGasConsumeDecorator(suite.app.AccountKeeper, ante.DefaultSigVerificationGasConsumer) 354 svd := ante.NewSigVerificationDecorator(suite.app.AccountKeeper, suite.clientCtx.TxConfig.SignModeHandler()) 355 antehandler := sdk.ChainAnteDecorators(spkd, svgc, svd) 356 357 // Determine gas consumption of antehandler with default params 358 before := suite.ctx.GasMeter().GasConsumed() 359 ctx, err := antehandler(suite.ctx, tx, false) 360 after := ctx.GasMeter().GasConsumed() 361 362 return after - before, err 363 } 364 365 func (suite *AnteTestSuite) TestIncrementSequenceDecorator() { 366 suite.SetupTest(true) // setup 367 suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() 368 369 priv, _, addr := testdata.KeyTestPubAddr() 370 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr) 371 suite.Require().NoError(acc.SetAccountNumber(uint64(50))) 372 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 373 374 msgs := []sdk.Msg{testdata.NewTestMsg(addr)} 375 suite.Require().NoError(suite.txBuilder.SetMsgs(msgs...)) 376 privs := []cryptotypes.PrivKey{priv} 377 accNums := []uint64{suite.app.AccountKeeper.GetAccount(suite.ctx, addr).GetAccountNumber()} 378 accSeqs := []uint64{suite.app.AccountKeeper.GetAccount(suite.ctx, addr).GetSequence()} 379 feeAmount := testdata.NewTestFeeAmount() 380 gasLimit := testdata.NewTestGasLimit() 381 suite.txBuilder.SetFeeAmount(feeAmount) 382 suite.txBuilder.SetGasLimit(gasLimit) 383 384 tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) 385 suite.Require().NoError(err) 386 387 isd := ante.NewIncrementSequenceDecorator(suite.app.AccountKeeper) 388 antehandler := sdk.ChainAnteDecorators(isd) 389 390 testCases := []struct { 391 ctx sdk.Context 392 simulate bool 393 expectedSeq uint64 394 }{ 395 {suite.ctx.WithIsReCheckTx(true), false, 1}, 396 {suite.ctx.WithIsCheckTx(true).WithIsReCheckTx(false), false, 2}, 397 {suite.ctx.WithIsReCheckTx(true), false, 3}, 398 {suite.ctx.WithIsReCheckTx(true), false, 4}, 399 {suite.ctx.WithIsReCheckTx(true), true, 5}, 400 } 401 402 for i, tc := range testCases { 403 _, err := antehandler(tc.ctx, tx, tc.simulate) 404 suite.Require().NoError(err, "unexpected error; tc #%d, %v", i, tc) 405 suite.Require().Equal(tc.expectedSeq, suite.app.AccountKeeper.GetAccount(suite.ctx, addr).GetSequence()) 406 } 407 }