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  }