From 6ec5722674221dcb8160c80029a37ef39d031c7e Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 7 Oct 2021 14:01:20 +0200 Subject: [PATCH 01/40] Add IsTipper --- client/tx/tx.go | 6 ++++++ x/auth/client/cli/validate_sigs.go | 5 ----- x/auth/middleware/sigverify.go | 12 +++++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/client/tx/tx.go b/client/tx/tx.go index 23de49941594..0fdce12cdad6 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -220,11 +220,17 @@ func Sign(txf Factory, name string, txBuilder client.TxBuilder, overwriteSig boo } } + var isTipper bool + if tip := txBuilder.GetTx().GetTip(); tip != nil { + isTipper = tip.Tipper == sdk.AccAddress(pubKey.Address()).String() + } + signerData := authsigning.SignerData{ ChainID: txf.chainID, AccountNumber: txf.accountNumber, Sequence: txf.sequence, SignerIndex: signerIndex, + IsTipper: isTipper, } // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 03acf833f13d..114cd6144598 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -112,11 +112,6 @@ func printAndValidateSigs( } err = authsigning.VerifySignature(pubKey, signingData, sig.Data, signModeHandler, sigTx) if err != nil { - return false - } - } - - cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg) } cmd.Println("") diff --git a/x/auth/middleware/sigverify.go b/x/auth/middleware/sigverify.go index 9ae464932684..79b0a0cf67f2 100644 --- a/x/auth/middleware/sigverify.go +++ b/x/auth/middleware/sigverify.go @@ -429,13 +429,13 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { } } -func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, isReCheckTx, simulate bool) error { +func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, sdkTx sdk.Tx, isReCheckTx, simulate bool) error { sdkCtx := sdk.UnwrapSDKContext(ctx) // no need to verify signatures on recheck tx if isReCheckTx { return nil } - sigTx, ok := tx.(authsigning.SigVerifiableTx) + sigTx, ok := sdkTx.(authsigning.SigVerifiableTx) if !ok { return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } @@ -481,6 +481,12 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, is if !genesis { accNum = acc.GetAccountNumber() } + + var isTipper bool + if tipTx, ok := sdkTx.(tx.TipTx); ok && tipTx.GetTip() != nil { + isTipper = tipTx.GetTip().Tipper == signerAddrs[i].String() + } + signerData := authsigning.SignerData{ ChainID: chainID, AccountNumber: accNum, @@ -488,7 +494,7 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, is } if !simulate { - err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svm.signModeHandler, tx) + err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svm.signModeHandler, sdkTx) if err != nil { var errMsg string if OnlyLegacyAminoSigners(sig.Data) { From 6eb5a10ea98da644d67c08ce8d8a65a80a74b1cd Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 7 Oct 2021 14:24:24 +0200 Subject: [PATCH 02/40] Use addr in signer data --- client/tx/tx.go | 21 +---- server/rosetta/converter.go | 1 + simapp/helpers/test_helpers.go | 1 + x/auth/client/cli/tx_multisign.go | 2 + x/auth/client/cli/validate_sigs.go | 1 + x/auth/middleware/sigverify.go | 6 +- x/auth/signing/sign_mode_handler.go | 6 +- x/auth/testutil/suite.go | 2 + x/auth/tx/amino_aux.go | 57 ----------- x/auth/tx/amino_aux_test.go | 141 ---------------------------- x/auth/tx/direct_aux.go | 22 ++++- x/auth/tx/legacy_amino_json.go | 2 +- x/auth/tx/mode_handler.go | 4 +- 13 files changed, 35 insertions(+), 231 deletions(-) delete mode 100644 x/auth/tx/amino_aux.go delete mode 100644 x/auth/tx/amino_aux_test.go diff --git a/client/tx/tx.go b/client/tx/tx.go index 0fdce12cdad6..315f8639b1d9 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -207,30 +207,11 @@ func Sign(txf Factory, name string, txBuilder client.TxBuilder, overwriteSig boo return err } - pubkeys, err := txBuilder.GetTx().GetPubKeys() - if err != nil { - return err - } - - signerIndex := 0 - for i, p := range pubkeys { - if p.Equals(pubKey) { - signerIndex = i - break - } - } - - var isTipper bool - if tip := txBuilder.GetTx().GetTip(); tip != nil { - isTipper = tip.Tipper == sdk.AccAddress(pubKey.Address()).String() - } - signerData := authsigning.SignerData{ ChainID: txf.chainID, AccountNumber: txf.accountNumber, Sequence: txf.sequence, - SignerIndex: signerIndex, - IsTipper: isTipper, + Address: sdk.AccAddress(pubKey.Address()), } // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on diff --git a/server/rosetta/converter.go b/server/rosetta/converter.go index 4fdd87c75b67..5ad0a86de7ce 100644 --- a/server/rosetta/converter.go +++ b/server/rosetta/converter.go @@ -722,6 +722,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // set the signer data signerData := authsigning.SignerData{ + Address: signer, ChainID: metadata.ChainID, AccountNumber: metadata.SignersData[i].AccountNumber, Sequence: metadata.SignersData[i].Sequence, diff --git a/simapp/helpers/test_helpers.go b/simapp/helpers/test_helpers.go index 9ccecbd976c4..956db67c7f1f 100644 --- a/simapp/helpers/test_helpers.go +++ b/simapp/helpers/test_helpers.go @@ -57,6 +57,7 @@ func GenTx(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, ch // 2nd round: once all signer infos are set, every signer can sign. for i, p := range priv { signerData := authsign.SignerData{ + Address: p.PubKey().Address().Bytes(), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index 4f33ac75212c..0cb9c1d1f3e3 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -129,6 +129,7 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { } signingData := signing.SignerData{ + Address: sdk.AccAddress(sigs[i].PubKey.Address()), ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), @@ -323,6 +324,7 @@ func makeBatchMultisignCmd() func(cmd *cobra.Command, args []string) error { multisigPub := pubKey.(*kmultisig.LegacyAminoPubKey) multisigSig := multisig.NewMultisig(len(multisigPub.PubKeys)) signingData := signing.SignerData{ + Address: pubKey.Address().Bytes(), ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 114cd6144598..b854849dbe8e 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -106,6 +106,7 @@ func printAndValidateSigs( } signingData := authsigning.SignerData{ + Address: sigAddr, ChainID: chainID, AccountNumber: accNum, Sequence: accSeq, diff --git a/x/auth/middleware/sigverify.go b/x/auth/middleware/sigverify.go index 79b0a0cf67f2..0aa59e1273f5 100644 --- a/x/auth/middleware/sigverify.go +++ b/x/auth/middleware/sigverify.go @@ -482,12 +482,8 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, sdkTx sdk.Tx, accNum = acc.GetAccountNumber() } - var isTipper bool - if tipTx, ok := sdkTx.(tx.TipTx); ok && tipTx.GetTip() != nil { - isTipper = tipTx.GetTip().Tipper == signerAddrs[i].String() - } - signerData := authsigning.SignerData{ + Address: signerAddrs[i], ChainID: chainID, AccountNumber: accNum, Sequence: acc.GetSequence(), diff --git a/x/auth/signing/sign_mode_handler.go b/x/auth/signing/sign_mode_handler.go index cf82b3f66d8e..ac76fc467463 100644 --- a/x/auth/signing/sign_mode_handler.go +++ b/x/auth/signing/sign_mode_handler.go @@ -23,6 +23,9 @@ type SignModeHandler interface { // SignerData is the specific information needed to sign a transaction that generally // isn't included in the transaction body itself type SignerData struct { + // The address of the signer. + Address sdk.AccAddress + // ChainID is the chain that this transaction is targeted ChainID string @@ -34,7 +37,4 @@ type SignerData struct { // since in SIGN_MODE_DIRECT the account sequence is already in the signer // info. Sequence uint64 - - // SignerIndex index of signer in the signer_infos array - SignerIndex int } diff --git a/x/auth/testutil/suite.go b/x/auth/testutil/suite.go index 253ce3409c5b..5ba12111fa19 100644 --- a/x/auth/testutil/suite.go +++ b/x/auth/testutil/suite.go @@ -127,6 +127,7 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { // sign transaction signerData := signing.SignerData{ + Address: addr, ChainID: "test", AccountNumber: 1, Sequence: seq1, @@ -137,6 +138,7 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { s.Require().NoError(err) signerData = signing.SignerData{ + Address: msigAddr, ChainID: "test", AccountNumber: 3, Sequence: mseq, diff --git a/x/auth/tx/amino_aux.go b/x/auth/tx/amino_aux.go deleted file mode 100644 index aa388a42a556..000000000000 --- a/x/auth/tx/amino_aux.go +++ /dev/null @@ -1,57 +0,0 @@ -package tx - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - - "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/cosmos/cosmos-sdk/x/auth/signing" -) - -var _ signing.SignModeHandler = signModeAminoAuxHandler{} - -// signModeAminoAuxHandler defines the SIGN_MODE_AMINO_AUX SignModeHandler -type signModeAminoAuxHandler struct{} - -// DefaultMode implements SignModeHandler.DefaultMode -func (signModeAminoAuxHandler) DefaultMode() signingtypes.SignMode { - return signingtypes.SignMode_SIGN_MODE_AMINO_AUX -} - -// Modes implements SignModeHandler.Modes -func (signModeAminoAuxHandler) Modes() []signingtypes.SignMode { - return []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_AMINO_AUX} -} - -// GetSignBytes implements SignModeHandler.GetSignBytes -func (signModeAminoAuxHandler) GetSignBytes( - mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx, -) ([]byte, error) { - - if mode != signingtypes.SignMode_SIGN_MODE_AMINO_AUX { - return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_AMINO_AUX, mode) - } - - protoTx, ok := tx.(*wrapper) - if !ok { - return nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx) - } - - if protoTx.txBodyHasUnknownNonCriticals { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, aminoNonCriticalFieldsError) - } - - body := protoTx.tx.Body - - if len(body.ExtensionOptions) != 0 || len(body.NonCriticalExtensionOptions) != 0 { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_AMINO_AUX does not support protobuf extension options.") - } - - return legacytx.StdSignAuxBytes( - data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), - protoTx.tx.AuthInfo.Tip.Amount, tx.GetMsgs(), protoTx.GetMemo(), - ), nil -} diff --git a/x/auth/tx/amino_aux_test.go b/x/auth/tx/amino_aux_test.go deleted file mode 100644 index 8f008ff84644..000000000000 --- a/x/auth/tx/amino_aux_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package tx - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/cosmos/cosmos-sdk/x/auth/signing" -) - -func TestAminoAuxHandler(t *testing.T) { - privKey, pubkey, addr := testdata.KeyTestPubAddr() - interfaceRegistry := codectypes.NewInterfaceRegistry() - interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) - marshaler := codec.NewProtoCodec(interfaceRegistry) - - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_AMINO_AUX}) - txBuilder := txConfig.NewTxBuilder() - - accountNumber := uint64(1) - chainId := "test-chain" - memo := "sometestmemo" - msgs := []sdk.Msg{testdata.NewTestMsg(addr)} - accSeq := uint64(2) // Arbitrary account sequence - timeout := uint64(10) - fee := txtypes.Fee{Amount: sdk.NewCoins(sdk.NewInt64Coin("atom", 150)), GasLimit: 20000} - tip := sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(1000))) - - err := txBuilder.SetMsgs(msgs...) - require.NoError(t, err) - txBuilder.SetMemo(memo) - txBuilder.SetFeeAmount(fee.Amount) - txBuilder.SetGasLimit(fee.GasLimit) - txBuilder.SetTimeoutHeight(timeout) - txBuilder.SetTip(&txtypes.Tip{ - Amount: tip, - Tipper: addr.String(), // Not needed when signing using AMINO_AUX, but putting here for clarity. - }) - - sigData := &signingtypes.SingleSignatureData{ - SignMode: signingtypes.SignMode_SIGN_MODE_AMINO_AUX, - } - - sig := signingtypes.SignatureV2{ - PubKey: pubkey, - Data: sigData, - Sequence: accSeq, - } - err = txBuilder.SetSignatures(sig) - require.NoError(t, err) - - signingData := signing.SignerData{ - ChainID: chainId, - AccountNumber: accountNumber, - Sequence: accSeq, - SignerIndex: 0, - } - - handler := signModeAminoAuxHandler{} - signBytes, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_AMINO_AUX, signingData, txBuilder.GetTx()) - require.NoError(t, err) - require.NotNil(t, signBytes) - - expectedSignBytes := legacytx.StdSignAuxBytes(chainId, accountNumber, accSeq, timeout, tip, msgs, memo) - require.NoError(t, err) - require.Equal(t, expectedSignBytes, signBytes) - - t.Log("verify that setting signature doesn't change sign bytes") - sigData.Signature, err = privKey.Sign(signBytes) - require.NoError(t, err) - err = txBuilder.SetSignatures(sig) - require.NoError(t, err) - signBytes, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_AMINO_AUX, signingData, txBuilder.GetTx()) - require.NoError(t, err) - require.Equal(t, expectedSignBytes, signBytes) - - // expect error with wrong sign mode - _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, txBuilder.GetTx()) - require.Error(t, err) - - // expect error with extension options - bldr := newBuilder() - buildTx(t, bldr) - any, err := codectypes.NewAnyWithValue(testdata.NewTestMsg()) - require.NoError(t, err) - bldr.tx.Body.ExtensionOptions = []*codectypes.Any{any} - tx := bldr.GetTx() - _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_AMINO_AUX, signingData, tx) - require.Error(t, err) - - // expect error with non-critical extension options - bldr = newBuilder() - buildTx(t, bldr) - bldr.tx.Body.NonCriticalExtensionOptions = []*codectypes.Any{any} - tx = bldr.GetTx() - _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_AMINO_AUX, signingData, tx) - require.Error(t, err) -} - -func TestAminoAuxHandler_DefaultMode(t *testing.T) { - handler := signModeAminoAuxHandler{} - require.Equal(t, signingtypes.SignMode_SIGN_MODE_AMINO_AUX, handler.DefaultMode()) -} - -func TestAminoAuxModeHandler_nonDIRECT_MODE(t *testing.T) { - invalidModes := []signingtypes.SignMode{ - signingtypes.SignMode_SIGN_MODE_DIRECT, - signingtypes.SignMode_SIGN_MODE_TEXTUAL, - signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - signingtypes.SignMode_SIGN_MODE_UNSPECIFIED, - signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, - } - for _, invalidMode := range invalidModes { - t.Run(invalidMode.String(), func(t *testing.T) { - var dh signModeAminoAuxHandler - var signingData signing.SignerData - _, err := dh.GetSignBytes(invalidMode, signingData, nil) - require.Error(t, err) - wantErr := fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_AMINO_AUX, invalidMode) - require.Equal(t, err, wantErr) - }) - } -} - -func TestAminoAuxModeHandler_nonProtoTx(t *testing.T) { - var ah signModeAminoAuxHandler - var signingData signing.SignerData - tx := new(nonProtoTx) - _, err := ah.GetSignBytes(signingtypes.SignMode_SIGN_MODE_AMINO_AUX, signingData, tx) - require.Error(t, err) - wantErr := fmt.Errorf("can only handle a protobuf Tx, got %T", tx) - require.Equal(t, err, wantErr) -} diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index cf6685967901..492a0f02954a 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -3,7 +3,9 @@ package tx import ( "fmt" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" types "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -39,13 +41,31 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx) } + if data.Address == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "got empty address in SIGN_MODE_LEGACY_AMINO_JSON handler") + } + + var pubKey *codectypes.Any + pubKeys, err := protoTx.GetPubKeys() + if err != nil { + return nil, err + } + for i, pk := range pubKeys { + if data.Address.Equals(sdk.AccAddress(pk.Address())) { + pubKey = protoTx.tx.AuthInfo.SignerInfos[i].PublicKey + } + } + if pubKey == nil { + return nil, sdkerrors.ErrInvalidRequest.Wrap("got empty pubKey in SIGN_MODE_DIRECT_AUX handler") + } + signDocDirectAux := types.SignDocDirectAux{ BodyBytes: protoTx.getBodyBytes(), ChainId: data.ChainID, AccountNumber: data.AccountNumber, Sequence: data.Sequence, Tip: protoTx.tx.AuthInfo.Tip, - PublicKey: protoTx.tx.AuthInfo.SignerInfos[data.SignerIndex].PublicKey, + PublicKey: pubKey, } return signDocDirectAux.Marshal() diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index ace31134e474..48b32c0ce1ba 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -43,7 +43,7 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, body := protoTx.tx.Body if len(body.ExtensionOptions) != 0 || len(body.NonCriticalExtensionOptions) != 0 { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options.") + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options") } return legacytx.StdSignBytes( diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go index 5ebd0a6c547e..232d496fd25f 100644 --- a/x/auth/tx/mode_handler.go +++ b/x/auth/tx/mode_handler.go @@ -14,7 +14,7 @@ var DefaultSignModes = []signingtypes.SignMode{ } // makeSignModeHandler returns the default protobuf SignModeHandler supporting -// SIGN_MODE_DIRECT and SIGN_MODE_LEGACY_AMINO_JSON. +// SIGN_MODE_DIRECT, SIGN_MODE_DIRECT_AUX and SIGN_MODE_LEGACY_AMINO_JSON. func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler { if len(modes) < 1 { panic(fmt.Errorf("no sign modes enabled")) @@ -30,8 +30,6 @@ func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler handlers[i] = signModeLegacyAminoJSONHandler{} case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX: handlers[i] = signModeDirectAuxHandler{} - case signingtypes.SignMode_SIGN_MODE_AMINO_AUX: - handlers[i] = signModeAminoAuxHandler{} default: panic(fmt.Errorf("unsupported sign mode %+v", mode)) } From 72a56cbc1a2dc6408a736d455bfd8842711e61c5 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 7 Oct 2021 15:15:35 +0200 Subject: [PATCH 03/40] Always populate addr in signer data --- x/auth/middleware/feegrant_test.go | 1 + x/auth/middleware/testutil_test.go | 1 + .../migrations/legacytx/amino_signing_test.go | 1 + x/auth/signing/handler_map_test.go | 1 + x/auth/signing/verify_test.go | 1 + x/auth/tx/direct_aux.go | 7 +++++- x/auth/tx/direct_aux_test.go | 1 + x/auth/tx/direct_test.go | 1 + x/auth/tx/legacy_amino_json.go | 24 ++++++++++++++++++- x/auth/tx/legacy_amino_json_test.go | 1 + 10 files changed, 37 insertions(+), 2 deletions(-) diff --git a/x/auth/middleware/feegrant_test.go b/x/auth/middleware/feegrant_test.go index d45b44160496..53caeb46c1f7 100644 --- a/x/auth/middleware/feegrant_test.go +++ b/x/auth/middleware/feegrant_test.go @@ -212,6 +212,7 @@ func genTxWithFeeGranter(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, // 2nd round: once all signer infos are set, every signer can sign. for i, p := range priv { signerData := authsign.SignerData{ + Address: sdk.AccAddress(p.PubKey().Address()), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/x/auth/middleware/testutil_test.go b/x/auth/middleware/testutil_test.go index 11cfaf72c37e..6f3e448dadbf 100644 --- a/x/auth/middleware/testutil_test.go +++ b/x/auth/middleware/testutil_test.go @@ -139,6 +139,7 @@ func (s *MWTestSuite) createTestTx(txBuilder client.TxBuilder, privs []cryptotyp sigsV2 = []signing.SignatureV2{} for i, priv := range privs { signerData := xauthsigning.SignerData{ + Address: sdk.AccAddress(priv.PubKey().Address()), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/x/auth/migrations/legacytx/amino_signing_test.go b/x/auth/migrations/legacytx/amino_signing_test.go index 7abccbfd8206..708dcf27c591 100644 --- a/x/auth/migrations/legacytx/amino_signing_test.go +++ b/x/auth/migrations/legacytx/amino_signing_test.go @@ -46,6 +46,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { handler := stdTxSignModeHandler{} signingData := signing.SignerData{ + Address: addr1, ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, diff --git a/x/auth/signing/handler_map_test.go b/x/auth/signing/handler_map_test.go index 5da162d3271f..d4b713e8c472 100644 --- a/x/auth/signing/handler_map_test.go +++ b/x/auth/signing/handler_map_test.go @@ -60,6 +60,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) { aminoJSONHandler := legacytx.NewStdTxSignModeHandler() signingData := signing.SignerData{ + Address: addr1, ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index 8ae55a3891a5..79dacf468258 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -49,6 +49,7 @@ func TestVerifySignature(t *testing.T) { msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := legacytx.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) signerData := signing.SignerData{ + Address: addr, ChainID: chainId, AccountNumber: acc.GetAccountNumber(), Sequence: acc.GetSequence(), diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 492a0f02954a..1c04ef80684d 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -59,11 +59,16 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, sdkerrors.ErrInvalidRequest.Wrap("got empty pubKey in SIGN_MODE_DIRECT_AUX handler") } + seq, err := getSequence(protoTx, data.Address) + if err != nil { + return nil, err + } + signDocDirectAux := types.SignDocDirectAux{ BodyBytes: protoTx.getBodyBytes(), ChainId: data.ChainID, AccountNumber: data.AccountNumber, - Sequence: data.Sequence, + Sequence: seq, Tip: protoTx.tx.AuthInfo.Tip, PublicKey: pubKey, } diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index 5930dd520213..a8bb445aadbe 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -53,6 +53,7 @@ func TestDirectAuxHandler(t *testing.T) { require.NoError(t, err) signingData := signing.SignerData{ + Address: addr, ChainID: "test-chain", AccountNumber: 1, } diff --git a/x/auth/tx/direct_test.go b/x/auth/tx/direct_test.go index bef1e81ed974..25806f7095a6 100644 --- a/x/auth/tx/direct_test.go +++ b/x/auth/tx/direct_test.go @@ -69,6 +69,7 @@ func TestDirectModeHandler(t *testing.T) { require.Len(t, modeHandler.Modes(), 1) signingData := signing.SignerData{ + Address: addr, ChainID: "test-chain", AccountNumber: 1, } diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index 48b32c0ce1ba..3e7517f508f4 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -46,9 +46,31 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options") } + addr := data.Address + seq, err := getSequence(protoTx, addr) + if err != nil { + return nil, err + } + return legacytx.StdSignBytes( - data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), + data.ChainID, data.AccountNumber, seq, protoTx.GetTimeoutHeight(), legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()}, tx.GetMsgs(), protoTx.GetMemo(), ), nil } + +// getSequence retrieves the sequence of the given address from the protoTx's +// signer infos. +func getSequence(protoTx *wrapper, addr sdk.AccAddress) (uint64, error) { + sigsV2, err := protoTx.GetSignaturesV2() + if err != nil { + return 0, err + } + for _, si := range sigsV2 { + if addr.Equals(sdk.AccAddress(si.PubKey.Address())) { + return si.Sequence, nil + } + } + + return 0, sdkerrors.ErrInvalidRequest.Wrapf("address %s not found in signer infos", addr) +} diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 9a4f3ff70864..43400b64393f 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -45,6 +45,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { handler := signModeLegacyAminoJSONHandler{} signingData := signing.SignerData{ + Address: addr1, ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, From c0bd50504d8a412e24577acf31ae5e30fd65d2c6 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 7 Oct 2021 15:21:34 +0200 Subject: [PATCH 04/40] fi error messages --- x/auth/tx/direct_aux.go | 4 ++-- x/auth/tx/legacy_amino_json.go | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 1c04ef80684d..bc8da5b9d289 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -42,7 +42,7 @@ func (signModeDirectAuxHandler) GetSignBytes( } if data.Address == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "got empty address in SIGN_MODE_LEGACY_AMINO_JSON handler") + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } var pubKey *codectypes.Any @@ -56,7 +56,7 @@ func (signModeDirectAuxHandler) GetSignBytes( } } if pubKey == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("got empty pubKey in SIGN_MODE_DIRECT_AUX handler") + return nil, sdkerrors.ErrInvalidRequest.Wrapf("got empty pubKey in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } seq, err := getSequence(protoTx, data.Address) diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index 3e7517f508f4..44464a73bc5c 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -43,10 +43,14 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, body := protoTx.tx.Body if len(body.ExtensionOptions) != 0 || len(body.NonCriticalExtensionOptions) != 0 { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options") + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s does not support protobuf extension options", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } addr := data.Address + if addr == nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) + } + seq, err := getSequence(protoTx, addr) if err != nil { return nil, err From 551f5f45d16e17d3305dd605cb75ca1755b7e716 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 11:57:52 +0200 Subject: [PATCH 05/40] make proto gen --- docs/core/proto-docs.md | 3 +- proto/cosmos/tx/signing/v1beta1/signing.proto | 4 - types/tx/signing/signing.pb.go | 78 +++++++++---------- x/auth/migrations/legacytx/stdsign_aux.go | 47 ----------- x/authz/query.pb.go | 2 +- 5 files changed, 38 insertions(+), 96 deletions(-) delete mode 100644 x/auth/migrations/legacytx/stdsign_aux.go diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index aaaaf20f1655..dbc0ff6b21ce 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -1279,7 +1279,7 @@ GrantAuthorization defines the GenesisState/GrantAuthorization type. ### QueryGranterGrantsRequest -QueryGranterGrantsRequest is the request type for the Query/Grants RPC method. +QueryGranterGrantsRequest is the request type for the Query/GranterGrants RPC method. | Field | Type | Label | Description | @@ -9400,7 +9400,6 @@ SignMode represents a signing mode with its own security guarantees. | SIGN_MODE_DIRECT | 1 | SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is verified with raw bytes from Tx. | | SIGN_MODE_TEXTUAL | 2 | SIGN_MODE_TEXTUAL is a future signing mode that will verify some human-readable textual representation on top of the binary representation from SIGN_MODE_DIRECT. It is currently not supported. | | SIGN_MODE_DIRECT_AUX | 3 | SIGN_MODE_DIRECT_AUX specifies a signing mode which uses SignDocDirectAux. As opposed to SIGN_MODE_DIRECT, this sign mode does not require signers signing over other signers' `signer_info`. It also allows for adding Tips in transactions. | -| SIGN_MODE_AMINO_AUX | 4 | SIGN_MODE_AMINO_AUX specifies a signing mode which uses SignDocAminoAux. | | SIGN_MODE_LEGACY_AMINO_JSON | 127 | SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses Amino JSON and will be removed in the future. | diff --git a/proto/cosmos/tx/signing/v1beta1/signing.proto b/proto/cosmos/tx/signing/v1beta1/signing.proto index 0a13282ac0b3..a87b405f93cf 100644 --- a/proto/cosmos/tx/signing/v1beta1/signing.proto +++ b/proto/cosmos/tx/signing/v1beta1/signing.proto @@ -27,10 +27,6 @@ enum SignMode { // for adding Tips in transactions. SIGN_MODE_DIRECT_AUX = 3; - // SIGN_MODE_AMINO_AUX specifies a signing mode which uses - // SignDocAminoAux. - SIGN_MODE_AMINO_AUX = 4; - // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses // Amino JSON and will be removed in the future. SIGN_MODE_LEGACY_AMINO_JSON = 127; diff --git a/types/tx/signing/signing.pb.go b/types/tx/signing/signing.pb.go index e5e1ec4770ea..41cdf01fcf20 100644 --- a/types/tx/signing/signing.pb.go +++ b/types/tx/signing/signing.pb.go @@ -43,9 +43,6 @@ const ( // require signers signing over other signers' `signer_info`. It also allows // for adding Tips in transactions. SignMode_SIGN_MODE_DIRECT_AUX SignMode = 3 - // SIGN_MODE_AMINO_AUX specifies a signing mode which uses - // SignDocAminoAux. - SignMode_SIGN_MODE_AMINO_AUX SignMode = 4 // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses // Amino JSON and will be removed in the future. SignMode_SIGN_MODE_LEGACY_AMINO_JSON SignMode = 127 @@ -56,7 +53,6 @@ var SignMode_name = map[int32]string{ 1: "SIGN_MODE_DIRECT", 2: "SIGN_MODE_TEXTUAL", 3: "SIGN_MODE_DIRECT_AUX", - 4: "SIGN_MODE_AMINO_AUX", 127: "SIGN_MODE_LEGACY_AMINO_JSON", } @@ -65,7 +61,6 @@ var SignMode_value = map[string]int32{ "SIGN_MODE_DIRECT": 1, "SIGN_MODE_TEXTUAL": 2, "SIGN_MODE_DIRECT_AUX": 3, - "SIGN_MODE_AMINO_AUX": 4, "SIGN_MODE_LEGACY_AMINO_JSON": 127, } @@ -403,43 +398,42 @@ func init() { } var fileDescriptor_9a54958ff3d0b1b9 = []byte{ - // 566 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x41, 0x4f, 0xd4, 0x4e, - 0x18, 0xc6, 0x5b, 0xb6, 0x10, 0x78, 0xf9, 0xe7, 0x9f, 0x3a, 0x2c, 0x71, 0xa9, 0xa6, 0x12, 0x3c, - 0x48, 0x4c, 0x98, 0x06, 0x38, 0x18, 0xbd, 0x95, 0xdd, 0xba, 0xac, 0xb0, 0x8b, 0xb6, 0x4b, 0x82, - 0x5e, 0x36, 0x6d, 0x77, 0xa8, 0x0d, 0xdb, 0x4e, 0xed, 0x4c, 0x0d, 0x3d, 0xf9, 0x15, 0xfc, 0x14, - 0x26, 0x7e, 0x0e, 0x2f, 0x1e, 0x39, 0x7a, 0x34, 0xf0, 0x19, 0xbc, 0x1b, 0xa6, 0xed, 0x16, 0x0d, - 0xc6, 0xb8, 0xa7, 0xcd, 0xbc, 0xcf, 0xd3, 0xdf, 0xfb, 0x4c, 0xde, 0x77, 0x16, 0x1e, 0xf9, 0x94, - 0x45, 0x94, 0x19, 0xfc, 0xdc, 0x60, 0x61, 0x10, 0x87, 0x71, 0x60, 0xbc, 0xdf, 0xf6, 0x08, 0x77, - 0xb7, 0xab, 0x33, 0x4e, 0x52, 0xca, 0x29, 0x5a, 0x2b, 0x8c, 0x98, 0x9f, 0xe3, 0x4a, 0x28, 0x8d, - 0xda, 0x56, 0xc9, 0xf0, 0xd3, 0x3c, 0xe1, 0xd4, 0x88, 0xb2, 0x09, 0x0f, 0x59, 0x58, 0x83, 0xaa, - 0x42, 0x41, 0xd2, 0xd6, 0x02, 0x4a, 0x83, 0x09, 0x31, 0xc4, 0xc9, 0xcb, 0x4e, 0x0d, 0x37, 0xce, - 0x0b, 0x69, 0xe3, 0x14, 0x9a, 0x4e, 0x18, 0xc4, 0x2e, 0xcf, 0x52, 0xd2, 0x21, 0xcc, 0x4f, 0xc3, - 0x84, 0xd3, 0x94, 0xa1, 0x01, 0x00, 0xab, 0xea, 0xac, 0x25, 0xaf, 0x37, 0x36, 0x97, 0x77, 0x30, - 0xfe, 0x63, 0x22, 0x7c, 0x0b, 0xc4, 0xbe, 0x41, 0xd8, 0xf8, 0xa1, 0xc0, 0xca, 0x2d, 0x1e, 0xb4, - 0x0b, 0x90, 0x64, 0xde, 0x24, 0xf4, 0x47, 0x67, 0x24, 0x6f, 0xc9, 0xeb, 0xf2, 0xe6, 0xf2, 0x4e, - 0x13, 0x17, 0x79, 0x71, 0x95, 0x17, 0x9b, 0x71, 0x6e, 0x2f, 0x15, 0xbe, 0x03, 0x92, 0xa3, 0x2e, - 0x28, 0x63, 0x97, 0xbb, 0xad, 0x39, 0x61, 0xdf, 0xfd, 0xb7, 0x58, 0xb8, 0xe3, 0x72, 0xd7, 0x16, - 0x00, 0xa4, 0xc1, 0x22, 0x23, 0xef, 0x32, 0x12, 0xfb, 0xa4, 0xd5, 0x58, 0x97, 0x37, 0x15, 0x7b, - 0x7a, 0xd6, 0xbe, 0x34, 0x40, 0xb9, 0xb6, 0xa2, 0x21, 0x2c, 0xb0, 0x30, 0x0e, 0x26, 0xa4, 0x8c, - 0xf7, 0x6c, 0x86, 0x7e, 0xd8, 0x11, 0x84, 0x7d, 0xc9, 0x2e, 0x59, 0xe8, 0x15, 0xcc, 0x8b, 0x29, - 0x95, 0x97, 0x78, 0x3a, 0x0b, 0xb4, 0x7f, 0x0d, 0xd8, 0x97, 0xec, 0x82, 0xa4, 0x8d, 0x60, 0xa1, - 0x68, 0x83, 0x9e, 0x80, 0x12, 0xd1, 0x71, 0x11, 0xf8, 0xff, 0x9d, 0x87, 0x7f, 0x61, 0xf7, 0xe9, - 0x98, 0xd8, 0xe2, 0x03, 0x74, 0x1f, 0x96, 0xa6, 0x43, 0x13, 0xc9, 0xfe, 0xb3, 0xeb, 0x82, 0xf6, - 0x59, 0x86, 0x79, 0xd1, 0x13, 0x1d, 0xc0, 0xa2, 0x17, 0x72, 0x37, 0x4d, 0xdd, 0x6a, 0x68, 0x46, - 0xd5, 0xa4, 0xd8, 0x49, 0x3c, 0x5d, 0xc1, 0xaa, 0x53, 0x9b, 0x46, 0x89, 0xeb, 0xf3, 0xbd, 0x90, - 0x9b, 0xd7, 0x9f, 0xd9, 0x53, 0x00, 0x72, 0x7e, 0xd9, 0xb5, 0x39, 0xb1, 0x6b, 0x33, 0x0d, 0xf5, - 0x06, 0x66, 0x6f, 0x1e, 0x1a, 0x2c, 0x8b, 0x1e, 0x7f, 0x92, 0x61, 0xb1, 0xba, 0x23, 0x5a, 0x83, - 0x55, 0xa7, 0xd7, 0x1d, 0x8c, 0xfa, 0x47, 0x1d, 0x6b, 0x74, 0x3c, 0x70, 0x5e, 0x5a, 0xed, 0xde, - 0xf3, 0x9e, 0xd5, 0x51, 0x25, 0xd4, 0x04, 0xb5, 0x96, 0x3a, 0x3d, 0xdb, 0x6a, 0x0f, 0x55, 0x19, - 0xad, 0xc2, 0x9d, 0xba, 0x3a, 0xb4, 0x4e, 0x86, 0xc7, 0xe6, 0xa1, 0x3a, 0x87, 0x5a, 0xd0, 0xfc, - 0xdd, 0x3c, 0x32, 0x8f, 0x4f, 0xd4, 0x06, 0xba, 0x0b, 0x2b, 0xb5, 0x62, 0xf6, 0x7b, 0x83, 0x23, - 0x21, 0x28, 0xe8, 0x01, 0xdc, 0xab, 0x85, 0x43, 0xab, 0x6b, 0xb6, 0x5f, 0x97, 0xfa, 0x0b, 0xe7, - 0x68, 0xa0, 0x7e, 0xd8, 0xeb, 0x7e, 0xbd, 0xd4, 0xe5, 0x8b, 0x4b, 0x5d, 0xfe, 0x7e, 0xa9, 0xcb, - 0x1f, 0xaf, 0x74, 0xe9, 0xe2, 0x4a, 0x97, 0xbe, 0x5d, 0xe9, 0xd2, 0x9b, 0xad, 0x20, 0xe4, 0x6f, - 0x33, 0x0f, 0xfb, 0x34, 0x32, 0xaa, 0x77, 0x2f, 0x7e, 0xb6, 0xd8, 0xf8, 0xcc, 0xe0, 0x79, 0x42, - 0x6e, 0xfe, 0x99, 0x78, 0x0b, 0xe2, 0xd5, 0xec, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x54, 0x1d, - 0xa5, 0xb2, 0x68, 0x04, 0x00, 0x00, + // 558 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xc1, 0x6e, 0xd3, 0x4c, + 0x10, 0xc7, 0xed, 0x26, 0xad, 0xda, 0xe9, 0xa7, 0x4f, 0x66, 0x49, 0xa5, 0xd4, 0x20, 0x53, 0x95, + 0x03, 0x15, 0x52, 0xd7, 0x6a, 0x72, 0x40, 0x70, 0x73, 0x12, 0x93, 0x86, 0x36, 0x09, 0xd8, 0x89, + 0x54, 0xb8, 0x58, 0xb6, 0xb3, 0x35, 0x56, 0x63, 0xaf, 0xf1, 0xae, 0x51, 0x7d, 0xe2, 0x09, 0x90, + 0x78, 0x0d, 0x9e, 0x83, 0x0b, 0xc7, 0x1e, 0x39, 0xa2, 0xe4, 0x19, 0xb8, 0xa3, 0xd8, 0x71, 0x12, + 0x50, 0x11, 0x22, 0x27, 0x6b, 0x66, 0xfe, 0xfb, 0x9b, 0xff, 0x6a, 0x66, 0x0d, 0x8f, 0x5c, 0xca, + 0x02, 0xca, 0x54, 0x7e, 0xad, 0x32, 0xdf, 0x0b, 0xfd, 0xd0, 0x53, 0xdf, 0x9f, 0x38, 0x84, 0xdb, + 0x27, 0x45, 0x8c, 0xa3, 0x98, 0x72, 0x8a, 0xf6, 0x73, 0x21, 0xe6, 0xd7, 0xb8, 0x28, 0xcc, 0x85, + 0xf2, 0xf1, 0x9c, 0xe1, 0xc6, 0x69, 0xc4, 0xa9, 0x1a, 0x24, 0x63, 0xee, 0x33, 0x7f, 0x09, 0x2a, + 0x12, 0x39, 0x49, 0xde, 0xf7, 0x28, 0xf5, 0xc6, 0x44, 0xcd, 0x22, 0x27, 0xb9, 0x54, 0xed, 0x30, + 0xcd, 0x4b, 0x87, 0x97, 0x50, 0x31, 0x7d, 0x2f, 0xb4, 0x79, 0x12, 0x93, 0x16, 0x61, 0x6e, 0xec, + 0x47, 0x9c, 0xc6, 0x0c, 0xf5, 0x00, 0x58, 0x91, 0x67, 0x55, 0xf1, 0xa0, 0x74, 0xb4, 0x5b, 0xc3, + 0xf8, 0x8f, 0x8e, 0xf0, 0x2d, 0x10, 0x63, 0x85, 0x70, 0xf8, 0xa3, 0x0c, 0x77, 0x6f, 0xd1, 0xa0, + 0x3a, 0x40, 0x94, 0x38, 0x63, 0xdf, 0xb5, 0xae, 0x48, 0x5a, 0x15, 0x0f, 0xc4, 0xa3, 0xdd, 0x5a, + 0x05, 0xe7, 0x7e, 0x71, 0xe1, 0x17, 0x6b, 0x61, 0x6a, 0xec, 0xe4, 0xba, 0x33, 0x92, 0xa2, 0x36, + 0x94, 0x47, 0x36, 0xb7, 0xab, 0x1b, 0x99, 0xbc, 0xfe, 0x6f, 0xb6, 0x70, 0xcb, 0xe6, 0xb6, 0x91, + 0x01, 0x90, 0x0c, 0xdb, 0x8c, 0xbc, 0x4b, 0x48, 0xe8, 0x92, 0x6a, 0xe9, 0x40, 0x3c, 0x2a, 0x1b, + 0x8b, 0x58, 0xfe, 0x52, 0x82, 0xf2, 0x4c, 0x8a, 0x06, 0xb0, 0xc5, 0xfc, 0xd0, 0x1b, 0x93, 0xb9, + 0xbd, 0x67, 0x6b, 0xf4, 0xc3, 0x66, 0x46, 0x38, 0x15, 0x8c, 0x39, 0x0b, 0xbd, 0x82, 0xcd, 0x6c, + 0x4a, 0xf3, 0x4b, 0x3c, 0x5d, 0x07, 0xda, 0x9d, 0x01, 0x4e, 0x05, 0x23, 0x27, 0xc9, 0x16, 0x6c, + 0xe5, 0x6d, 0xd0, 0x13, 0x28, 0x07, 0x74, 0x94, 0x1b, 0xfe, 0xbf, 0xf6, 0xf0, 0x2f, 0xec, 0x2e, + 0x1d, 0x11, 0x23, 0x3b, 0x80, 0xee, 0xc3, 0xce, 0x62, 0x68, 0x99, 0xb3, 0xff, 0x8c, 0x65, 0x42, + 0xfe, 0x2c, 0xc2, 0x66, 0xd6, 0x13, 0x9d, 0xc1, 0xb6, 0xe3, 0x73, 0x3b, 0x8e, 0xed, 0x62, 0x68, + 0x6a, 0xd1, 0x24, 0xdf, 0x49, 0xbc, 0x58, 0xc1, 0xa2, 0x53, 0x93, 0x06, 0x91, 0xed, 0xf2, 0x86, + 0xcf, 0xb5, 0xd9, 0x31, 0x63, 0x01, 0x40, 0xe6, 0x2f, 0xbb, 0xb6, 0x91, 0xed, 0xda, 0x5a, 0x43, + 0x5d, 0xc1, 0x34, 0x36, 0xa1, 0xc4, 0x92, 0xe0, 0xf1, 0x47, 0x11, 0xb6, 0x8b, 0x3b, 0xa2, 0x7d, + 0xd8, 0x33, 0x3b, 0xed, 0x9e, 0xd5, 0xed, 0xb7, 0x74, 0x6b, 0xd8, 0x33, 0x5f, 0xea, 0xcd, 0xce, + 0xf3, 0x8e, 0xde, 0x92, 0x04, 0x54, 0x01, 0x69, 0x59, 0x6a, 0x75, 0x0c, 0xbd, 0x39, 0x90, 0x44, + 0xb4, 0x07, 0x77, 0x96, 0xd9, 0x81, 0x7e, 0x31, 0x18, 0x6a, 0xe7, 0xd2, 0x06, 0xaa, 0x42, 0xe5, + 0x77, 0xb1, 0xa5, 0x0d, 0x2f, 0xa4, 0x12, 0x7a, 0x00, 0xf7, 0x96, 0x95, 0x73, 0xbd, 0xad, 0x35, + 0x5f, 0x5b, 0x5a, 0xb7, 0xd3, 0xeb, 0x5b, 0x2f, 0xcc, 0x7e, 0x4f, 0xfa, 0xd0, 0x68, 0x7f, 0x9d, + 0x28, 0xe2, 0xcd, 0x44, 0x11, 0xbf, 0x4f, 0x14, 0xf1, 0xd3, 0x54, 0x11, 0x6e, 0xa6, 0x8a, 0xf0, + 0x6d, 0xaa, 0x08, 0x6f, 0x8e, 0x3d, 0x9f, 0xbf, 0x4d, 0x1c, 0xec, 0xd2, 0x40, 0x2d, 0x9e, 0x77, + 0xf6, 0x39, 0x66, 0xa3, 0x2b, 0x95, 0xa7, 0x11, 0x59, 0xfd, 0x67, 0x38, 0x5b, 0xd9, 0xe3, 0xa8, + 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xda, 0x51, 0x6b, 0x5b, 0x4f, 0x04, 0x00, 0x00, } func (m *SignatureDescriptors) Marshal() (dAtA []byte, err error) { diff --git a/x/auth/migrations/legacytx/stdsign_aux.go b/x/auth/migrations/legacytx/stdsign_aux.go deleted file mode 100644 index 5ba8539e747d..000000000000 --- a/x/auth/migrations/legacytx/stdsign_aux.go +++ /dev/null @@ -1,47 +0,0 @@ -package legacytx - -import ( - "encoding/json" - "fmt" - - "github.com/cosmos/cosmos-sdk/codec/legacy" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type StdSignDocAux struct { - AccountNumber uint64 `json:"account_number" yaml:"account_number"` - Sequence uint64 `json:"sequence" yaml:"sequence"` - TimeoutHeight uint64 `json:"timeout_height,omitempty" yaml:"timeout_height"` - ChainID string `json:"chain_id" yaml:"chain_id"` - Memo string `json:"memo" yaml:"memo"` - Msgs []json.RawMessage `json:"msgs" yaml:"msgs"` - Tip sdk.Coins `json:"tip" yaml:"tip"` -} - -// StdSignBytes returns the bytes to sign for a transaction. -func StdSignAuxBytes(chainID string, accnum, sequence, timeout uint64, tip sdk.Coins, msgs []sdk.Msg, memo string) []byte { - msgsBytes := make([]json.RawMessage, 0, len(msgs)) - for _, msg := range msgs { - legacyMsg, ok := msg.(LegacyMsg) - if !ok { - panic(fmt.Errorf("expected %T when using AMINO_AUX", (*LegacyMsg)(nil))) - } - - msgsBytes = append(msgsBytes, json.RawMessage(legacyMsg.GetSignBytes())) - } - - bz, err := legacy.Cdc.MarshalJSON(StdSignDocAux{ - AccountNumber: accnum, - ChainID: chainID, - Memo: memo, - Msgs: msgsBytes, - Sequence: sequence, - TimeoutHeight: timeout, - Tip: tip, - }) - if err != nil { - panic(err) - } - - return sdk.MustSortJSON(bz) -} diff --git a/x/authz/query.pb.go b/x/authz/query.pb.go index 681c9f40092c..92e7b4f8a3ba 100644 --- a/x/authz/query.pb.go +++ b/x/authz/query.pb.go @@ -156,7 +156,7 @@ func (m *QueryGrantsResponse) GetPagination() *query.PageResponse { return nil } -// QueryGranterGrantsRequest is the request type for the Query/Grants RPC method. +// QueryGranterGrantsRequest is the request type for the Query/GranterGrants RPC method. type QueryGranterGrantsRequest struct { Granter string `protobuf:"bytes,1,opt,name=granter,proto3" json:"granter,omitempty"` // pagination defines an pagination for the request. From 76b8dff248616c2a0137f7bc8c41c46a4f48ec52 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 12:32:48 +0200 Subject: [PATCH 06/40] fix build --- x/auth/client/cli/validate_sigs.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index b854849dbe8e..857f3b1e0369 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -113,6 +113,11 @@ func printAndValidateSigs( } err = authsigning.VerifySignature(pubKey, signingData, sig.Data, signModeHandler, sigTx) if err != nil { + return false + } + } + + cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg) } cmd.Println("") From e285150cfb743267cef9033aee57a7a9a4f8b3ce Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 12:53:41 +0200 Subject: [PATCH 07/40] Add fields to sign docs and sign mode handler --- types/tx/tips.go | 11 +++++++++++ x/auth/migrations/legacytx/stdsign.go | 2 +- x/auth/migrations/legacytx/stdtx.go | 12 ++++++++++-- x/auth/tx/legacy_amino_json.go | 22 +++++++++++++++++++++- 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 types/tx/tips.go diff --git a/types/tx/tips.go b/types/tx/tips.go new file mode 100644 index 000000000000..ca8afb36d5ae --- /dev/null +++ b/types/tx/tips.go @@ -0,0 +1,11 @@ +package tx + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TipTx defines the interface to be implemented by Txs that handle Tips. +type TipTx interface { + sdk.FeeTx + GetTip() *Tip +} diff --git a/x/auth/migrations/legacytx/stdsign.go b/x/auth/migrations/legacytx/stdsign.go index d22e3786d9f0..05a680054dc6 100644 --- a/x/auth/migrations/legacytx/stdsign.go +++ b/x/auth/migrations/legacytx/stdsign.go @@ -47,6 +47,7 @@ type StdSignDoc struct { Memo string `json:"memo" yaml:"memo"` Fee json.RawMessage `json:"fee" yaml:"fee"` Msgs []json.RawMessage `json:"msgs" yaml:"msgs"` + Tip StdTip `json:"tip,omitempty" yaml:"tip"` } // StdSignBytes returns the bytes to sign for a transaction. @@ -106,7 +107,6 @@ func (ss StdSignature) MarshalYAML() (interface{}, error) { pk = ss.PubKey.String() } - bz, err := yaml.Marshal(struct { PubKey string `json:"pub_key"` Signature string `json:"signature"` diff --git a/x/auth/migrations/legacytx/stdtx.go b/x/auth/migrations/legacytx/stdtx.go index 55ec38e603cc..c5bb2cb640e4 100644 --- a/x/auth/migrations/legacytx/stdtx.go +++ b/x/auth/migrations/legacytx/stdtx.go @@ -25,8 +25,10 @@ var ( // which must be above some miminum to be accepted into the mempool. // [Deprecated] type StdFee struct { - Amount sdk.Coins `json:"amount" yaml:"amount"` - Gas uint64 `json:"gas" yaml:"gas"` + Amount sdk.Coins `json:"amount" yaml:"amount"` + Gas uint64 `json:"gas" yaml:"gas"` + Payer string `json:"payer,omitempty" yaml:"payer"` + Granter string `json:"granter,omitempty" yaml:"granter"` } // Deprecated: NewStdFee returns a new instance of StdFee @@ -70,6 +72,12 @@ func (fee StdFee) GasPrices() sdk.DecCoins { return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas))) } +// StdTip is the tips used in a tipped transaction. +type StdTip struct { + Amount sdk.Coins `json:"amount" yaml:"amount"` + Tipper string `json:"gas" yaml:"gas"` +} + // StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures. // It only works with Amino, please prefer the new protobuf Tx in types/tx. // NOTE: the first signature is the fee payer (Signatures must not be nil). diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index 44464a73bc5c..93aefbb36c53 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + typestx "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -56,9 +57,28 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, return nil, err } + // We set a convention that if the tipper signs with LEGACY_AMINO_JSON, then + // they sign over empty fees and 0 gas. + var isTipper bool + if addr == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "got empty address in SIGN_MODE_LEGACY_AMINO_JSON handler") + } + if tipTx, ok := tx.(typestx.TipTx); ok && tipTx.GetTip() != nil { + isTipper = tipTx.GetTip().Tipper == addr.String() + } + + if isTipper { + return legacytx.StdSignBytes( + data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), + // The tipper signs over 0 fee and 0 gas, no feepayer, no feegranter by convention. + legacytx.StdFee{}, + tx.GetMsgs(), protoTx.GetMemo(), + ), nil + } + return legacytx.StdSignBytes( data.ChainID, data.AccountNumber, seq, protoTx.GetTimeoutHeight(), - legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()}, + legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas(), Payer: protoTx.FeePayer().String(), Granter: protoTx.FeeGranter().String()}, tx.GetMsgs(), protoTx.GetMemo(), ), nil } From 3f0402150fe04d492fce1c24fd2f66cbd708b204 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 15:17:18 +0200 Subject: [PATCH 08/40] Remove getSequence --- x/auth/tx/direct_aux.go | 7 +------ x/auth/tx/legacy_amino_json.go | 28 +--------------------------- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index bc8da5b9d289..1bd2a8378617 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -59,16 +59,11 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, sdkerrors.ErrInvalidRequest.Wrapf("got empty pubKey in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } - seq, err := getSequence(protoTx, data.Address) - if err != nil { - return nil, err - } - signDocDirectAux := types.SignDocDirectAux{ BodyBytes: protoTx.getBodyBytes(), ChainId: data.ChainID, AccountNumber: data.AccountNumber, - Sequence: seq, + Sequence: data.Sequence, Tip: protoTx.tx.AuthInfo.Tip, PublicKey: pubKey, } diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index 44464a73bc5c..fea9d78a9bd3 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -46,35 +46,9 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s does not support protobuf extension options", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } - addr := data.Address - if addr == nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) - } - - seq, err := getSequence(protoTx, addr) - if err != nil { - return nil, err - } - return legacytx.StdSignBytes( - data.ChainID, data.AccountNumber, seq, protoTx.GetTimeoutHeight(), + data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()}, tx.GetMsgs(), protoTx.GetMemo(), ), nil } - -// getSequence retrieves the sequence of the given address from the protoTx's -// signer infos. -func getSequence(protoTx *wrapper, addr sdk.AccAddress) (uint64, error) { - sigsV2, err := protoTx.GetSignaturesV2() - if err != nil { - return 0, err - } - for _, si := range sigsV2 { - if addr.Equals(sdk.AccAddress(si.PubKey.Address())) { - return si.Sequence, nil - } - } - - return 0, sdkerrors.ErrInvalidRequest.Wrapf("address %s not found in signer infos", addr) -} From a33a5cd91dfbd74f5d2ef4f26dc8b0ca15d79ecc Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:12:27 +0200 Subject: [PATCH 09/40] Update x/auth/migrations/legacytx/stdtx.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- x/auth/migrations/legacytx/stdtx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/migrations/legacytx/stdtx.go b/x/auth/migrations/legacytx/stdtx.go index c5bb2cb640e4..68f3b330eae8 100644 --- a/x/auth/migrations/legacytx/stdtx.go +++ b/x/auth/migrations/legacytx/stdtx.go @@ -75,7 +75,7 @@ func (fee StdFee) GasPrices() sdk.DecCoins { // StdTip is the tips used in a tipped transaction. type StdTip struct { Amount sdk.Coins `json:"amount" yaml:"amount"` - Tipper string `json:"gas" yaml:"gas"` + Tipper string `json:"tipper" yaml:"tipper"` } // StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures. From a5d11b36d1c0a1c71190481c7418d1ccc1acb4ef Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:13:21 +0200 Subject: [PATCH 10/40] Update x/auth/migrations/legacytx/stdsign.go Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- x/auth/migrations/legacytx/stdsign.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/migrations/legacytx/stdsign.go b/x/auth/migrations/legacytx/stdsign.go index 05a680054dc6..6ee3de54300f 100644 --- a/x/auth/migrations/legacytx/stdsign.go +++ b/x/auth/migrations/legacytx/stdsign.go @@ -47,7 +47,7 @@ type StdSignDoc struct { Memo string `json:"memo" yaml:"memo"` Fee json.RawMessage `json:"fee" yaml:"fee"` Msgs []json.RawMessage `json:"msgs" yaml:"msgs"` - Tip StdTip `json:"tip,omitempty" yaml:"tip"` + Tip *StdTip `json:"tip,omitempty" yaml:"tip"` } // StdSignBytes returns the bytes to sign for a transaction. From 894a7ce25e80aed6852a33799204d14de6c17394 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:30:40 +0200 Subject: [PATCH 11/40] Use addressCodec --- client/tx/tx.go | 2 +- server/rosetta/client_online.go | 17 +++++++---------- server/rosetta/converter.go | 2 +- simapp/helpers/test_helpers.go | 2 +- simapp/params/proto.go | 6 +++++- x/auth/client/cli/tx_multisign.go | 4 ++-- x/auth/client/cli/validate_sigs.go | 2 +- x/auth/keeper/bech32_codec.go | 2 +- x/auth/keeper/keeper.go | 2 +- x/auth/middleware/feegrant_test.go | 2 +- x/auth/middleware/sigverify.go | 2 +- x/auth/middleware/testutil_test.go | 2 +- .../migrations/legacytx/amino_signing_test.go | 2 +- x/auth/signing/handler_map_test.go | 2 +- x/auth/signing/sign_mode_handler.go | 2 +- x/auth/signing/verify_test.go | 2 +- x/auth/testutil/suite.go | 4 ++-- x/auth/tx/config.go | 11 +++++------ x/auth/tx/direct_aux.go | 18 +++++++++++++----- x/auth/tx/direct_aux_test.go | 2 +- x/auth/tx/direct_test.go | 2 +- x/auth/tx/legacy_amino_json_test.go | 2 +- x/auth/tx/mode_handler.go | 6 ++++-- 23 files changed, 54 insertions(+), 44 deletions(-) diff --git a/client/tx/tx.go b/client/tx/tx.go index 315f8639b1d9..0a4adde5ac10 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -211,7 +211,7 @@ func Sign(txf Factory, name string, txBuilder client.TxBuilder, overwriteSig boo ChainID: txf.chainID, AccountNumber: txf.accountNumber, Sequence: txf.sequence, - Address: sdk.AccAddress(pubKey.Address()), + Address: sdk.AccAddress(pubKey.Address()).String(), } // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index 0a34b8b1a878..6390b1790e76 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -8,26 +8,22 @@ import ( "strconv" "time" - "github.com/cosmos/cosmos-sdk/version" - - abcitypes "github.com/tendermint/tendermint/abci/types" - rosettatypes "github.com/coinbase/rosetta-sdk-go/types" - "google.golang.org/grpc/metadata" - + abcitypes "github.com/tendermint/tendermint/abci/types" + tmrpc "github.com/tendermint/tendermint/rpc/client" "github.com/tendermint/tendermint/rpc/client/http" "google.golang.org/grpc" + "google.golang.org/grpc/metadata" crgerrs "github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors" crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types" - sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" auth "github.com/cosmos/cosmos-sdk/x/auth/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" - - tmrpc "github.com/tendermint/tendermint/rpc/client" ) // interface assertion @@ -60,7 +56,8 @@ func NewClient(cfg *Config) (*Client, error) { v = "unknown" } - txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes) + addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) + txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes, addrCdc) var supportedOperations []string for _, ii := range cfg.InterfaceRegistry.ListImplementations(sdk.MsgInterfaceProtoName) { diff --git a/server/rosetta/converter.go b/server/rosetta/converter.go index 5ad0a86de7ce..7a7f6e019896 100644 --- a/server/rosetta/converter.go +++ b/server/rosetta/converter.go @@ -722,7 +722,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // set the signer data signerData := authsigning.SignerData{ - Address: signer, + Address: signer.String(), ChainID: metadata.ChainID, AccountNumber: metadata.SignersData[i].AccountNumber, Sequence: metadata.SignersData[i].Sequence, diff --git a/simapp/helpers/test_helpers.go b/simapp/helpers/test_helpers.go index 956db67c7f1f..3c7b8ca42bad 100644 --- a/simapp/helpers/test_helpers.go +++ b/simapp/helpers/test_helpers.go @@ -57,7 +57,7 @@ func GenTx(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, ch // 2nd round: once all signer infos are set, every signer can sign. for i, p := range priv { signerData := authsign.SignerData{ - Address: p.PubKey().Address().Bytes(), + Address: sdk.AccAddress(p.PubKey().Address()).String(), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/simapp/params/proto.go b/simapp/params/proto.go index 2a38fff04008..5403b037e3ab 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -6,6 +6,8 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -18,10 +20,12 @@ func MakeTestEncodingConfig() EncodingConfig { interfaceRegistry := types.NewInterfaceRegistry() codec := codec.NewProtoCodec(interfaceRegistry) + addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) + return EncodingConfig{ InterfaceRegistry: interfaceRegistry, Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addrCdc), Amino: cdc, } } diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index 0cb9c1d1f3e3..9d7ad05fc5f8 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -129,7 +129,7 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { } signingData := signing.SignerData{ - Address: sdk.AccAddress(sigs[i].PubKey.Address()), + Address: sdk.AccAddress(sigs[i].PubKey.Address()).String(), ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), @@ -324,7 +324,7 @@ func makeBatchMultisignCmd() func(cmd *cobra.Command, args []string) error { multisigPub := pubKey.(*kmultisig.LegacyAminoPubKey) multisigSig := multisig.NewMultisig(len(multisigPub.PubKeys)) signingData := signing.SignerData{ - Address: pubKey.Address().Bytes(), + Address: sdk.AccAddress(pubKey.Address()).String(), ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 857f3b1e0369..9cf9d8a6f0fe 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -106,7 +106,7 @@ func printAndValidateSigs( } signingData := authsigning.SignerData{ - Address: sigAddr, + Address: sigAddr.String(), ChainID: chainID, AccountNumber: accNum, Sequence: accSeq, diff --git a/x/auth/keeper/bech32_codec.go b/x/auth/keeper/bech32_codec.go index b107b67de9f4..563271f27d42 100644 --- a/x/auth/keeper/bech32_codec.go +++ b/x/auth/keeper/bech32_codec.go @@ -13,7 +13,7 @@ type bech32Codec struct { var _ address.Codec = &bech32Codec{} -func newBech32Codec(prefix string) bech32Codec { +func NewBech32Codec(prefix string) address.Codec { return bech32Codec{prefix} } diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index 25592115a3e9..3a50eedcee5d 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -87,7 +87,7 @@ func NewAccountKeeper( permAddrs[name] = types.NewPermissionsForAddress(name, perms) } - bech32Codec := newBech32Codec(bech32Prefix) + bech32Codec := NewBech32Codec(bech32Prefix) return AccountKeeper{ key: key, diff --git a/x/auth/middleware/feegrant_test.go b/x/auth/middleware/feegrant_test.go index 53caeb46c1f7..62033d4f830e 100644 --- a/x/auth/middleware/feegrant_test.go +++ b/x/auth/middleware/feegrant_test.go @@ -212,7 +212,7 @@ func genTxWithFeeGranter(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, // 2nd round: once all signer infos are set, every signer can sign. for i, p := range priv { signerData := authsign.SignerData{ - Address: sdk.AccAddress(p.PubKey().Address()), + Address: sdk.AccAddress(p.PubKey().Address()).String(), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/x/auth/middleware/sigverify.go b/x/auth/middleware/sigverify.go index 0aa59e1273f5..0a90a183f4f3 100644 --- a/x/auth/middleware/sigverify.go +++ b/x/auth/middleware/sigverify.go @@ -483,7 +483,7 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, sdkTx sdk.Tx, } signerData := authsigning.SignerData{ - Address: signerAddrs[i], + Address: signerAddrs[i].String(), ChainID: chainID, AccountNumber: accNum, Sequence: acc.GetSequence(), diff --git a/x/auth/middleware/testutil_test.go b/x/auth/middleware/testutil_test.go index 6f3e448dadbf..130b1bbde9be 100644 --- a/x/auth/middleware/testutil_test.go +++ b/x/auth/middleware/testutil_test.go @@ -139,7 +139,7 @@ func (s *MWTestSuite) createTestTx(txBuilder client.TxBuilder, privs []cryptotyp sigsV2 = []signing.SignatureV2{} for i, priv := range privs { signerData := xauthsigning.SignerData{ - Address: sdk.AccAddress(priv.PubKey().Address()), + Address: sdk.AccAddress(priv.PubKey().Address()).String(), ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], diff --git a/x/auth/migrations/legacytx/amino_signing_test.go b/x/auth/migrations/legacytx/amino_signing_test.go index 708dcf27c591..db9777c1ab23 100644 --- a/x/auth/migrations/legacytx/amino_signing_test.go +++ b/x/auth/migrations/legacytx/amino_signing_test.go @@ -46,7 +46,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { handler := stdTxSignModeHandler{} signingData := signing.SignerData{ - Address: addr1, + Address: addr1.String(), ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, diff --git a/x/auth/signing/handler_map_test.go b/x/auth/signing/handler_map_test.go index d4b713e8c472..4d1fe76917ec 100644 --- a/x/auth/signing/handler_map_test.go +++ b/x/auth/signing/handler_map_test.go @@ -60,7 +60,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) { aminoJSONHandler := legacytx.NewStdTxSignModeHandler() signingData := signing.SignerData{ - Address: addr1, + Address: addr1.String(), ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, diff --git a/x/auth/signing/sign_mode_handler.go b/x/auth/signing/sign_mode_handler.go index ac76fc467463..efa8f96e4cbc 100644 --- a/x/auth/signing/sign_mode_handler.go +++ b/x/auth/signing/sign_mode_handler.go @@ -24,7 +24,7 @@ type SignModeHandler interface { // isn't included in the transaction body itself type SignerData struct { // The address of the signer. - Address sdk.AccAddress + Address string // ChainID is the chain that this transaction is targeted ChainID string diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index 79dacf468258..f1984a7f7e12 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -49,7 +49,7 @@ func TestVerifySignature(t *testing.T) { msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := legacytx.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) signerData := signing.SignerData{ - Address: addr, + Address: addr.String(), ChainID: chainId, AccountNumber: acc.GetAccountNumber(), Sequence: acc.GetSequence(), diff --git a/x/auth/testutil/suite.go b/x/auth/testutil/suite.go index 5ba12111fa19..809c67564229 100644 --- a/x/auth/testutil/suite.go +++ b/x/auth/testutil/suite.go @@ -127,7 +127,7 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { // sign transaction signerData := signing.SignerData{ - Address: addr, + Address: addr.String(), ChainID: "test", AccountNumber: 1, Sequence: seq1, @@ -138,7 +138,7 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { s.Require().NoError(err) signerData = signing.SignerData{ - Address: msigAddr, + Address: msigAddr.String(), ChainID: "test", AccountNumber: 3, Sequence: mseq, diff --git a/x/auth/tx/config.go b/x/auth/tx/config.go index 8402423dbf77..9c4df1ca1683 100644 --- a/x/auth/tx/config.go +++ b/x/auth/tx/config.go @@ -3,12 +3,11 @@ package tx import ( "fmt" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -23,9 +22,9 @@ type config struct { // NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and sign modes. The // first enabled sign mode will become the default sign mode. -func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode) client.TxConfig { +func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, addrCdc address.Codec) client.TxConfig { return &config{ - handler: makeSignModeHandler(enabledSignModes), + handler: makeSignModeHandler(enabledSignModes, addrCdc), decoder: DefaultTxDecoder(protoCodec), encoder: DefaultTxEncoder(), jsonDecoder: DefaultJSONTxDecoder(protoCodec), diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 1bd2a8378617..b56597b190c8 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -1,21 +1,24 @@ package tx import ( + "bytes" "fmt" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" types "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/signing" ) var _ signing.SignModeHandler = signModeDirectAuxHandler{} // signModeDirectAuxHandler defines the SIGN_MODE_DIRECT_AUX SignModeHandler -type signModeDirectAuxHandler struct{} +type signModeDirectAuxHandler struct { + addrCdc address.Codec +} // DefaultMode implements SignModeHandler.DefaultMode func (signModeDirectAuxHandler) DefaultMode() signingtypes.SignMode { @@ -28,7 +31,7 @@ func (signModeDirectAuxHandler) Modes() []signingtypes.SignMode { } // GetSignBytes implements SignModeHandler.GetSignBytes -func (signModeDirectAuxHandler) GetSignBytes( +func (h signModeDirectAuxHandler) GetSignBytes( mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx, ) ([]byte, error) { @@ -41,17 +44,22 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx) } - if data.Address == nil { + if data.Address == "" { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } + addrBz, err := h.addrCdc.StringToBytes(data.Address) + if err != nil { + return nil, err + } + var pubKey *codectypes.Any pubKeys, err := protoTx.GetPubKeys() if err != nil { return nil, err } for i, pk := range pubKeys { - if data.Address.Equals(sdk.AccAddress(pk.Address())) { + if bytes.Equal(addrBz, pk.Address()) { pubKey = protoTx.tx.AuthInfo.SignerInfos[i].PublicKey } } diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index a8bb445aadbe..359c4b570ed4 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -53,7 +53,7 @@ func TestDirectAuxHandler(t *testing.T) { require.NoError(t, err) signingData := signing.SignerData{ - Address: addr, + Address: addr.String(), ChainID: "test-chain", AccountNumber: 1, } diff --git a/x/auth/tx/direct_test.go b/x/auth/tx/direct_test.go index 25806f7095a6..3ca6756a4122 100644 --- a/x/auth/tx/direct_test.go +++ b/x/auth/tx/direct_test.go @@ -69,7 +69,7 @@ func TestDirectModeHandler(t *testing.T) { require.Len(t, modeHandler.Modes(), 1) signingData := signing.SignerData{ - Address: addr, + Address: addr.String(), ChainID: "test-chain", AccountNumber: 1, } diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 43400b64393f..540b3b464761 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -45,7 +45,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { handler := signModeLegacyAminoJSONHandler{} signingData := signing.SignerData{ - Address: addr1, + Address: addr1.String(), ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go index 232d496fd25f..94e80739cba5 100644 --- a/x/auth/tx/mode_handler.go +++ b/x/auth/tx/mode_handler.go @@ -3,6 +3,7 @@ package tx import ( "fmt" + "github.com/cosmos/cosmos-sdk/types/address" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -11,11 +12,12 @@ import ( var DefaultSignModes = []signingtypes.SignMode{ signingtypes.SignMode_SIGN_MODE_DIRECT, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, } // makeSignModeHandler returns the default protobuf SignModeHandler supporting // SIGN_MODE_DIRECT, SIGN_MODE_DIRECT_AUX and SIGN_MODE_LEGACY_AMINO_JSON. -func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler { +func makeSignModeHandler(modes []signingtypes.SignMode, addrCdc address.Codec) signing.SignModeHandler { if len(modes) < 1 { panic(fmt.Errorf("no sign modes enabled")) } @@ -29,7 +31,7 @@ func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON: handlers[i] = signModeLegacyAminoJSONHandler{} case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX: - handlers[i] = signModeDirectAuxHandler{} + handlers[i] = signModeDirectAuxHandler{addrCdc} default: panic(fmt.Errorf("unsupported sign mode %+v", mode)) } From 6c66bfb16c346b36a298720b0c6df42b707dd7c3 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:40:02 +0200 Subject: [PATCH 12/40] NewTxConfig with addrCdc --- simapp/params/encoding.go | 9 +++++++++ simapp/params/proto.go | 6 +----- x/auth/tx/config_test.go | 2 +- x/auth/tx/direct_aux_test.go | 4 +++- x/auth/tx/direct_test.go | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index 8ff9ea04b39b..0abed993cb36 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -4,6 +4,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" ) // EncodingConfig specifies the concrete encoding types to use for a given app. @@ -14,3 +17,9 @@ type EncodingConfig struct { TxConfig client.TxConfig Amino *codec.LegacyAmino } + +// NewBech32Codec creates an address codec used to converting addresses to and +// from string/bytes, based on bech32 using `sdk.Bech32MainPrefix`. +func NewBech32Codec() address.Codec { + return keeper.NewBech32Codec(sdk.Bech32MainPrefix) +} diff --git a/simapp/params/proto.go b/simapp/params/proto.go index 5403b037e3ab..8f9660c31635 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -6,8 +6,6 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -20,12 +18,10 @@ func MakeTestEncodingConfig() EncodingConfig { interfaceRegistry := types.NewInterfaceRegistry() codec := codec.NewProtoCodec(interfaceRegistry) - addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) - return EncodingConfig{ InterfaceRegistry: interfaceRegistry, Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addrCdc), + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, NewBech32Codec()), Amino: cdc, } } diff --git a/x/auth/tx/config_test.go b/x/auth/tx/config_test.go index b20cf1ce4e85..3d15863426f1 100644 --- a/x/auth/tx/config_test.go +++ b/x/auth/tx/config_test.go @@ -18,5 +18,5 @@ func TestGenerator(t *testing.T) { std.RegisterInterfaces(interfaceRegistry) interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) protoCodec := codec.NewProtoCodec(interfaceRegistry) - suite.Run(t, testutil.NewTxConfigTestSuite(NewTxConfig(protoCodec, DefaultSignModes))) + suite.Run(t, testutil.NewTxConfigTestSuite(NewTxConfig(protoCodec, DefaultSignModes, nil))) } diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index 359c4b570ed4..1b37bbf2263a 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -12,6 +12,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -20,8 +21,9 @@ func TestDirectAuxHandler(t *testing.T) { interfaceRegistry := codectypes.NewInterfaceRegistry() interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) + addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}) + txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}, addrCdc) txBuilder := txConfig.NewTxBuilder() memo := "sometestmemo" diff --git a/x/auth/tx/direct_test.go b/x/auth/tx/direct_test.go index 3ca6756a4122..24b3d3cb9190 100644 --- a/x/auth/tx/direct_test.go +++ b/x/auth/tx/direct_test.go @@ -21,7 +21,7 @@ func TestDirectModeHandler(t *testing.T) { interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT}) + txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT}, nil) txBuilder := txConfig.NewTxBuilder() memo := "sometestmemo" From debee8d783d4b24ea8d978b4c8df1389b4045cf3 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:56:35 +0200 Subject: [PATCH 13/40] REmove simapp.NewBech32 --- simapp/params/encoding.go | 9 +-------- simapp/params/proto.go | 6 +++++- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index 0abed993cb36..7a51ab21d4db 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -4,22 +4,15 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" ) // EncodingConfig specifies the concrete encoding types to use for a given app. // This is provided for compatibility between protobuf and amino implementations. type EncodingConfig struct { + AddrCdc address.Codec InterfaceRegistry types.InterfaceRegistry Codec codec.Codec TxConfig client.TxConfig Amino *codec.LegacyAmino } - -// NewBech32Codec creates an address codec used to converting addresses to and -// from string/bytes, based on bech32 using `sdk.Bech32MainPrefix`. -func NewBech32Codec() address.Codec { - return keeper.NewBech32Codec(sdk.Bech32MainPrefix) -} diff --git a/simapp/params/proto.go b/simapp/params/proto.go index 8f9660c31635..9a8a0b7d3940 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -6,6 +6,8 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -17,11 +19,13 @@ func MakeTestEncodingConfig() EncodingConfig { cdc := codec.NewLegacyAmino() interfaceRegistry := types.NewInterfaceRegistry() codec := codec.NewProtoCodec(interfaceRegistry) + addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ + AddrCdc: addrCdc, InterfaceRegistry: interfaceRegistry, Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, NewBech32Codec()), + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addrCdc), Amino: cdc, } } From e3a7c3573db219ed343492432b895a523695d823 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 11:51:13 +0200 Subject: [PATCH 14/40] Move bech32 stuff to x/auth/address --- client/tx/legacy_test.go | 2 +- server/rosetta/client_online.go | 13 +++++----- server/rosetta/converter_test.go | 3 ++- simapp/params/amino.go | 3 +++ simapp/params/encoding.go | 2 +- simapp/params/proto.go | 8 +++---- .../bech32_codec.go => address/bech32.go} | 24 ++++++++++--------- x/auth/keeper/keeper.go | 10 ++++---- x/auth/middleware/feegrant_test.go | 3 ++- x/auth/tx/config.go | 4 ++-- x/auth/tx/direct_aux.go | 4 ++-- x/auth/tx/direct_aux_test.go | 6 ++--- x/auth/tx/mode_handler.go | 4 ++-- 13 files changed, 46 insertions(+), 40 deletions(-) rename x/auth/{keeper/bech32_codec.go => address/bech32.go} (51%) diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 65949a038fa1..f2d806bd6468 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -61,7 +61,7 @@ type TestSuite struct { func (s *TestSuite) SetupSuite() { encCfg := simapp.MakeTestEncodingConfig() s.encCfg = encCfg - s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes) + s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes, nil) s.aminoCfg = legacytx.StdTxConfig{Cdc: encCfg.Amino} } diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index 6390b1790e76..1f285f4b2612 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -20,9 +20,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/address" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - auth "github.com/cosmos/cosmos-sdk/x/auth/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -38,7 +38,7 @@ type Client struct { config *Config - auth auth.QueryClient + auth authtypes.QueryClient bank bank.QueryClient tmRPC tmrpc.Client @@ -56,8 +56,7 @@ func NewClient(cfg *Config) (*Client, error) { v = "unknown" } - addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) - txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes, addrCdc) + txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) var supportedOperations []string for _, ii := range cfg.InterfaceRegistry.ListImplementations(sdk.MsgInterfaceProtoName) { @@ -103,7 +102,7 @@ func (c *Client) Bootstrap() error { return err } - authClient := auth.NewQueryClient(grpcConn) + authClient := authtypes.NewQueryClient(grpcConn) bankClient := bank.NewQueryClient(grpcConn) c.auth = authClient @@ -134,7 +133,7 @@ func (c *Client) accountInfo(ctx context.Context, addr string, height *int64) (* ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, strHeight) } - accountInfo, err := c.auth.Account(ctx, &auth.QueryAccountRequest{ + accountInfo, err := c.auth.Account(ctx, &authtypes.QueryAccountRequest{ Address: addr, }) if err != nil { diff --git a/server/rosetta/converter_test.go b/server/rosetta/converter_test.go index 1177d33405df..f7e2b36a46b4 100644 --- a/server/rosetta/converter_test.go +++ b/server/rosetta/converter_test.go @@ -7,6 +7,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/x/auth/address" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/client" @@ -44,7 +45,7 @@ func (s *ConverterTestSuite) SetupTest() { s.unsignedTxBytes = unsignedTxBytes // instantiate converter cdc, ir := rosetta.MakeCodec() - txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes) + txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) s.c = rosetta.NewConverter(cdc, ir, txConfig) // add utils s.ir = ir diff --git a/simapp/params/amino.go b/simapp/params/amino.go index cdf86d0ea2e0..39bf4d54e5c5 100644 --- a/simapp/params/amino.go +++ b/simapp/params/amino.go @@ -5,6 +5,7 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" ) @@ -16,8 +17,10 @@ func MakeTestEncodingConfig() EncodingConfig { cdc := codec.NewLegacyAmino() interfaceRegistry := types.NewInterfaceRegistry() marshaler := codec.NewAminoCodec(cdc) + addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ + AddressCdc: addressCdc, InterfaceRegistry: interfaceRegistry, Marshaler: marshaler, TxConfig: legacytx.StdTxConfig{Cdc: cdc}, diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index 7a51ab21d4db..fa55cccf1377 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -10,7 +10,7 @@ import ( // EncodingConfig specifies the concrete encoding types to use for a given app. // This is provided for compatibility between protobuf and amino implementations. type EncodingConfig struct { - AddrCdc address.Codec + addressCdc address.Codec InterfaceRegistry types.InterfaceRegistry Codec codec.Codec TxConfig client.TxConfig diff --git a/simapp/params/proto.go b/simapp/params/proto.go index 9a8a0b7d3940..aef884599530 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -19,13 +19,13 @@ func MakeTestEncodingConfig() EncodingConfig { cdc := codec.NewLegacyAmino() interfaceRegistry := types.NewInterfaceRegistry() codec := codec.NewProtoCodec(interfaceRegistry) - addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) + addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ - AddrCdc: addrCdc, + addressCdc: addressCdc, InterfaceRegistry: interfaceRegistry, Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addrCdc), + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addressCdc), Amino: cdc, } } diff --git a/x/auth/keeper/bech32_codec.go b/x/auth/address/bech32.go similarity index 51% rename from x/auth/keeper/bech32_codec.go rename to x/auth/address/bech32.go index 563271f27d42..494601a1b088 100644 --- a/x/auth/keeper/bech32_codec.go +++ b/x/auth/address/bech32.go @@ -1,4 +1,4 @@ -package keeper +package address import ( sdk "github.com/cosmos/cosmos-sdk/types" @@ -7,24 +7,26 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -type bech32Codec struct { - bech32Prefix string +// Bech32Codec is a address.Codec based on bech32 encoding. +type Bech32Codec struct { + Bech32Prefix string } -var _ address.Codec = &bech32Codec{} +var _ address.Codec = &Bech32Codec{} +// NewBech32Codec creates a new address.Codec based on bech32 encoding. func NewBech32Codec(prefix string) address.Codec { - return bech32Codec{prefix} + return Bech32Codec{prefix} } -// StringToBytes encodes text to bytes -func (bc bech32Codec) StringToBytes(text string) ([]byte, error) { +// StringToBytes encodes text to bytes. +func (bc Bech32Codec) StringToBytes(text string) ([]byte, error) { hrp, bz, err := bech32.DecodeAndConvert(text) if err != nil { return nil, err } - if hrp != bc.bech32Prefix { + if hrp != bc.Bech32Prefix { return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "hrp does not match bech32Prefix") } @@ -35,9 +37,9 @@ func (bc bech32Codec) StringToBytes(text string) ([]byte, error) { return bz, nil } -// BytesToString decodes bytes to text -func (bc bech32Codec) BytesToString(bz []byte) (string, error) { - text, err := bech32.ConvertAndEncode(bc.bech32Prefix, bz) +// BytesToString decodes bytes to text. +func (bc Bech32Codec) BytesToString(bz []byte) (string, error) { + text, err := bech32.ConvertAndEncode(bc.Bech32Prefix, bz) if err != nil { return "", err } diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index 3a50eedcee5d..d9ec085425fc 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -9,11 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/codec" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authaddress "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -87,7 +87,7 @@ func NewAccountKeeper( permAddrs[name] = types.NewPermissionsForAddress(name, perms) } - bech32Codec := NewBech32Codec(bech32Prefix) + bech32Codec := authaddress.NewBech32Codec(bech32Prefix) return AccountKeeper{ key: key, @@ -247,10 +247,10 @@ func (ak AccountKeeper) GetCodec() codec.BinaryCodec { return ak.cdc } // add getter for bech32Prefix func (ak AccountKeeper) getBech32Prefix() (string, error) { - bech32Codec, ok := ak.addressCdc.(bech32Codec) + bech32Codec, ok := ak.addressCdc.(authaddress.Bech32Codec) if !ok { return "", errors.New("unable cast addressCdc to bech32Codec") } - return bech32Codec.bech32Prefix, nil + return bech32Codec.Bech32Prefix, nil } diff --git a/x/auth/middleware/feegrant_test.go b/x/auth/middleware/feegrant_test.go index 62033d4f830e..9ab7f7cede57 100644 --- a/x/auth/middleware/feegrant_test.go +++ b/x/auth/middleware/feegrant_test.go @@ -16,6 +16,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/middleware" authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/tx" @@ -28,7 +29,7 @@ func (s *MWTestSuite) TestDeductFeesNoDelegation() { ctx := s.SetupTest(false) // setup app := s.app - protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(app.InterfaceRegistry()), tx.DefaultSignModes) + protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(app.InterfaceRegistry()), tx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) txHandler := middleware.ComposeMiddlewares( noopTxHandler{}, diff --git a/x/auth/tx/config.go b/x/auth/tx/config.go index 9c4df1ca1683..d69448250457 100644 --- a/x/auth/tx/config.go +++ b/x/auth/tx/config.go @@ -22,9 +22,9 @@ type config struct { // NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and sign modes. The // first enabled sign mode will become the default sign mode. -func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, addrCdc address.Codec) client.TxConfig { +func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, addressCdc address.Codec) client.TxConfig { return &config{ - handler: makeSignModeHandler(enabledSignModes, addrCdc), + handler: makeSignModeHandler(enabledSignModes, addressCdc), decoder: DefaultTxDecoder(protoCodec), encoder: DefaultTxEncoder(), jsonDecoder: DefaultJSONTxDecoder(protoCodec), diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index b56597b190c8..45890e911f12 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -17,7 +17,7 @@ var _ signing.SignModeHandler = signModeDirectAuxHandler{} // signModeDirectAuxHandler defines the SIGN_MODE_DIRECT_AUX SignModeHandler type signModeDirectAuxHandler struct { - addrCdc address.Codec + addressCdc address.Codec } // DefaultMode implements SignModeHandler.DefaultMode @@ -48,7 +48,7 @@ func (h signModeDirectAuxHandler) GetSignBytes( return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } - addrBz, err := h.addrCdc.StringToBytes(data.Address) + addrBz, err := h.addressCdc.StringToBytes(data.Address) if err != nil { return nil, err } diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index 1b37bbf2263a..435eed43b879 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -12,7 +12,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -21,9 +21,9 @@ func TestDirectAuxHandler(t *testing.T) { interfaceRegistry := codectypes.NewInterfaceRegistry() interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) - addrCdc := keeper.NewBech32Codec(sdk.Bech32MainPrefix) + addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}, addrCdc) + txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}, addressCdc) txBuilder := txConfig.NewTxBuilder() memo := "sometestmemo" diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go index 94e80739cba5..ab1b2dc88897 100644 --- a/x/auth/tx/mode_handler.go +++ b/x/auth/tx/mode_handler.go @@ -17,7 +17,7 @@ var DefaultSignModes = []signingtypes.SignMode{ // makeSignModeHandler returns the default protobuf SignModeHandler supporting // SIGN_MODE_DIRECT, SIGN_MODE_DIRECT_AUX and SIGN_MODE_LEGACY_AMINO_JSON. -func makeSignModeHandler(modes []signingtypes.SignMode, addrCdc address.Codec) signing.SignModeHandler { +func makeSignModeHandler(modes []signingtypes.SignMode, addressCdc address.Codec) signing.SignModeHandler { if len(modes) < 1 { panic(fmt.Errorf("no sign modes enabled")) } @@ -31,7 +31,7 @@ func makeSignModeHandler(modes []signingtypes.SignMode, addrCdc address.Codec) s case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON: handlers[i] = signModeLegacyAminoJSONHandler{} case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX: - handlers[i] = signModeDirectAuxHandler{addrCdc} + handlers[i] = signModeDirectAuxHandler{addressCdc} default: panic(fmt.Errorf("unsupported sign mode %+v", mode)) } From dfd1d820b9508bc39149ca8066360efa35f635be Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 11:58:28 +0200 Subject: [PATCH 15/40] Add changelog --- CHANGELOG.md | 1 + client/tx/legacy_test.go | 2 +- server/rosetta/client_online.go | 8 ++++---- simapp/params/encoding.go | 2 +- simapp/params/proto.go | 2 +- x/auth/client/cli/validate_sigs.go | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c32cf5f40ab..dcb7f0ea9130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,6 +97,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Move Msg routers from BaseApp to middlewares. * Move Baseapp panic recovery into a middleware. * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}`. +* [\#10322](https://github.com/cosmos/cosmos-sdk/pull/10322) The `tx.NewTxConfig` function takes a new parameter of type `address.Codec` used to encode and decode addresses. As such, a new field `AddressCdc` has been added to `simapp.EncodingConfig`. ### Client Breaking Changes diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index f2d806bd6468..94c43301eb07 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -61,7 +61,7 @@ type TestSuite struct { func (s *TestSuite) SetupSuite() { encCfg := simapp.MakeTestEncodingConfig() s.encCfg = encCfg - s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes, nil) + s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes, s.encCfg.AddressCdc) s.aminoCfg = legacytx.StdTxConfig{Cdc: encCfg.Amino} } diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index 1f285f4b2612..eebaa67e1e9e 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -22,7 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth/address" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + auth "github.com/cosmos/cosmos-sdk/x/auth/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -38,7 +38,7 @@ type Client struct { config *Config - auth authtypes.QueryClient + auth auth.QueryClient bank bank.QueryClient tmRPC tmrpc.Client @@ -102,7 +102,7 @@ func (c *Client) Bootstrap() error { return err } - authClient := authtypes.NewQueryClient(grpcConn) + authClient := auth.NewQueryClient(grpcConn) bankClient := bank.NewQueryClient(grpcConn) c.auth = authClient @@ -133,7 +133,7 @@ func (c *Client) accountInfo(ctx context.Context, addr string, height *int64) (* ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, strHeight) } - accountInfo, err := c.auth.Account(ctx, &authtypes.QueryAccountRequest{ + accountInfo, err := c.auth.Account(ctx, &auth.QueryAccountRequest{ Address: addr, }) if err != nil { diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index fa55cccf1377..daec7b8d8a3e 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -10,7 +10,7 @@ import ( // EncodingConfig specifies the concrete encoding types to use for a given app. // This is provided for compatibility between protobuf and amino implementations. type EncodingConfig struct { - addressCdc address.Codec + AddressCdc address.Codec InterfaceRegistry types.InterfaceRegistry Codec codec.Codec TxConfig client.TxConfig diff --git a/simapp/params/proto.go b/simapp/params/proto.go index aef884599530..905eaf1ae06e 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -22,7 +22,7 @@ func MakeTestEncodingConfig() EncodingConfig { addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ - addressCdc: addressCdc, + AddressCdc: addressCdc, InterfaceRegistry: interfaceRegistry, Codec: codec, TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addressCdc), diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 9cf9d8a6f0fe..51e46e84c411 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -117,7 +117,7 @@ func printAndValidateSigs( } } - cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg) + cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg) } cmd.Println("") From 7092ee8d553537557c24ecd394b2fd9df645f2e7 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 12:06:51 +0200 Subject: [PATCH 16/40] Move address.Codec to x/auth --- simapp/params/encoding.go | 2 +- x/auth/address/bech32.go | 5 ++--- {types => x/auth}/address/codec.go | 0 x/auth/keeper/keeper.go | 7 +++---- x/auth/tx/config.go | 2 +- x/auth/tx/direct_aux.go | 2 +- x/auth/tx/direct_aux_test.go | 2 +- x/auth/tx/mode_handler.go | 2 +- 8 files changed, 10 insertions(+), 12 deletions(-) rename {types => x/auth}/address/codec.go (100%) diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index daec7b8d8a3e..edbf0ca0cd2b 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/types/address" + "github.com/cosmos/cosmos-sdk/x/auth/address" ) // EncodingConfig specifies the concrete encoding types to use for a given app. diff --git a/x/auth/address/bech32.go b/x/auth/address/bech32.go index 494601a1b088..b0adde5a69ab 100644 --- a/x/auth/address/bech32.go +++ b/x/auth/address/bech32.go @@ -2,7 +2,6 @@ package address import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" "github.com/cosmos/cosmos-sdk/types/bech32" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -12,10 +11,10 @@ type Bech32Codec struct { Bech32Prefix string } -var _ address.Codec = &Bech32Codec{} +var _ Codec = &Bech32Codec{} // NewBech32Codec creates a new address.Codec based on bech32 encoding. -func NewBech32Codec(prefix string) address.Codec { +func NewBech32Codec(prefix string) Codec { return Bech32Codec{prefix} } diff --git a/types/address/codec.go b/x/auth/address/codec.go similarity index 100% rename from types/address/codec.go rename to x/auth/address/codec.go diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index d9ec085425fc..16a6e83e475b 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -11,9 +11,8 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - authaddress "github.com/cosmos/cosmos-sdk/x/auth/address" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -87,7 +86,7 @@ func NewAccountKeeper( permAddrs[name] = types.NewPermissionsForAddress(name, perms) } - bech32Codec := authaddress.NewBech32Codec(bech32Prefix) + bech32Codec := address.NewBech32Codec(bech32Prefix) return AccountKeeper{ key: key, @@ -247,7 +246,7 @@ func (ak AccountKeeper) GetCodec() codec.BinaryCodec { return ak.cdc } // add getter for bech32Prefix func (ak AccountKeeper) getBech32Prefix() (string, error) { - bech32Codec, ok := ak.addressCdc.(authaddress.Bech32Codec) + bech32Codec, ok := ak.addressCdc.(address.Bech32Codec) if !ok { return "", errors.New("unable cast addressCdc to bech32Codec") } diff --git a/x/auth/tx/config.go b/x/auth/tx/config.go index d69448250457..0b57b03092b2 100644 --- a/x/auth/tx/config.go +++ b/x/auth/tx/config.go @@ -6,8 +6,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 45890e911f12..9695591db160 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -6,10 +6,10 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" types "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index 435eed43b879..28f73c1126ee 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -60,7 +60,7 @@ func TestDirectAuxHandler(t *testing.T) { AccountNumber: 1, } - modeHandler := signModeDirectAuxHandler{} + modeHandler := signModeDirectAuxHandler{addressCdc} signBytes, err := modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, signingData, txBuilder.GetTx()) require.NoError(t, err) require.NotNil(t, signBytes) diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go index ab1b2dc88897..07a462ceefbb 100644 --- a/x/auth/tx/mode_handler.go +++ b/x/auth/tx/mode_handler.go @@ -3,8 +3,8 @@ package tx import ( "fmt" - "github.com/cosmos/cosmos-sdk/types/address" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) From bac6349bacb50af4c41574cead3cc953f87e0586 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 12:13:14 +0200 Subject: [PATCH 17/40] Fix test --- x/auth/client/cli/tx_multisign.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index 9d7ad05fc5f8..77358de95a07 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -128,14 +128,14 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("set the chain id with either the --chain-id flag or config file") } - signingData := signing.SignerData{ - Address: sdk.AccAddress(sigs[i].PubKey.Address()).String(), - ChainID: txFactory.ChainID(), - AccountNumber: txFactory.AccountNumber(), - Sequence: txFactory.Sequence(), - } - for _, sig := range sigs { + signingData := signing.SignerData{ + Address: sdk.AccAddress(sig.PubKey.Address()).String(), + ChainID: txFactory.ChainID(), + AccountNumber: txFactory.AccountNumber(), + Sequence: txFactory.Sequence(), + } + err = signing.VerifySignature(sig.PubKey, signingData, sig.Data, txCfg.SignModeHandler(), txBuilder.GetTx()) if err != nil { addr, _ := sdk.AccAddressFromHex(sig.PubKey.Address().String()) From ab495df3102c24ea552c7edb32d6e3b507516bf4 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 15:36:09 +0200 Subject: [PATCH 18/40] Add tests for tipper and feepayer --- x/auth/migrations/legacytx/amino_signing.go | 2 +- .../migrations/legacytx/amino_signing_test.go | 2 +- x/auth/migrations/legacytx/stdsign.go | 9 +- x/auth/migrations/legacytx/stdsignmsg.go | 2 +- x/auth/migrations/legacytx/stdtx_test.go | 58 +++++++++-- x/auth/tx/builder.go | 5 + x/auth/tx/legacy_amino_json.go | 25 +++-- x/auth/tx/legacy_amino_json_test.go | 98 +++++++++++++++---- 8 files changed, 158 insertions(+), 43 deletions(-) diff --git a/x/auth/migrations/legacytx/amino_signing.go b/x/auth/migrations/legacytx/amino_signing.go index 2f5b1d4a4218..4115efa70493 100644 --- a/x/auth/migrations/legacytx/amino_signing.go +++ b/x/auth/migrations/legacytx/amino_signing.go @@ -43,7 +43,7 @@ func (stdTxSignModeHandler) GetSignBytes(mode signingtypes.SignMode, data signin } return StdSignBytes( - data.ChainID, data.AccountNumber, data.Sequence, stdTx.GetTimeoutHeight(), StdFee{Amount: stdTx.GetFee(), Gas: stdTx.GetGas()}, tx.GetMsgs(), stdTx.GetMemo(), + data.ChainID, data.AccountNumber, data.Sequence, stdTx.GetTimeoutHeight(), StdFee{Amount: stdTx.GetFee(), Gas: stdTx.GetGas()}, tx.GetMsgs(), stdTx.GetMemo(), nil, ), nil } diff --git a/x/auth/migrations/legacytx/amino_signing_test.go b/x/auth/migrations/legacytx/amino_signing_test.go index db9777c1ab23..a5141880925b 100644 --- a/x/auth/migrations/legacytx/amino_signing_test.go +++ b/x/auth/migrations/legacytx/amino_signing_test.go @@ -54,7 +54,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.NoError(t, err) - expectedSignBz := StdSignBytes(chainId, accNum, seqNum, timeoutHeight, fee, msgs, memo) + expectedSignBz := StdSignBytes(chainId, accNum, seqNum, timeoutHeight, fee, msgs, memo, nil) require.Equal(t, expectedSignBz, signBz) diff --git a/x/auth/migrations/legacytx/stdsign.go b/x/auth/migrations/legacytx/stdsign.go index 6ee3de54300f..7eb5f0349c7f 100644 --- a/x/auth/migrations/legacytx/stdsign.go +++ b/x/auth/migrations/legacytx/stdsign.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -51,7 +52,7 @@ type StdSignDoc struct { } // StdSignBytes returns the bytes to sign for a transaction. -func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string) []byte { +func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string, tip *tx.Tip) []byte { msgsBytes := make([]json.RawMessage, 0, len(msgs)) for _, msg := range msgs { legacyMsg, ok := msg.(LegacyMsg) @@ -62,6 +63,11 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgsBytes = append(msgsBytes, json.RawMessage(legacyMsg.GetSignBytes())) } + var stdTip *StdTip + if tip != nil { + stdTip = &StdTip{Amount: tip.Amount, Tipper: tip.Tipper} + } + bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{ AccountNumber: accnum, ChainID: chainID, @@ -70,6 +76,7 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, Msgs: msgsBytes, Sequence: sequence, TimeoutHeight: timeout, + Tip: stdTip, }) if err != nil { panic(err) diff --git a/x/auth/migrations/legacytx/stdsignmsg.go b/x/auth/migrations/legacytx/stdsignmsg.go index 07ee29a06324..56e68b0f5b6f 100644 --- a/x/auth/migrations/legacytx/stdsignmsg.go +++ b/x/auth/migrations/legacytx/stdsignmsg.go @@ -21,7 +21,7 @@ type StdSignMsg struct { // get message bytes func (msg StdSignMsg) Bytes() []byte { - return StdSignBytes(msg.ChainID, msg.AccountNumber, msg.Sequence, msg.TimeoutHeight, msg.Fee, msg.Msgs, msg.Memo) + return StdSignBytes(msg.ChainID, msg.AccountNumber, msg.Sequence, msg.TimeoutHeight, msg.Fee, msg.Msgs, msg.Memo, nil) } func (msg StdSignMsg) UnpackInterfaces(unpacker types.AnyUnpacker) error { diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index ec70281f6828..850c74d3b318 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -41,7 +42,7 @@ func NewTestStdFee() StdFee { func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey, accNums []uint64, seqs []uint64, timeout uint64, fee StdFee) sdk.Tx { sigs := make([]StdSignature, len(privs)) for i, priv := range privs { - signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "") + signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "", nil) sig, err := priv.Sign(signBytes) if err != nil { @@ -80,24 +81,67 @@ func TestStdSignBytes(t *testing.T) { fee StdFee msgs []sdk.Msg memo string + tip *tx.Tip } defaultFee := NewTestStdFee() + defaultTip := &tx.Tip{Tipper: addr.String(), Amount: sdk.NewCoins(sdk.NewInt64Coin("tiptoken", 150))} tests := []struct { + name string args args want string }{ { - args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"}, - fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\",\"timeout_height\":\"10\"}", addr), + "with timeout height", + args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","timeout_height":"10"}`, addr), }, { - args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"}, - fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\"}", addr), + "no timeout height", + args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "empty fee", + args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "no fee payer and fee granter (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), + }, + { + "no fee payer (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), + }, + { + "no fee granter (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), + }, + { + "no tip (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), + }, + { + "no fee, with tip (omitempty)", + args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr), + }, + { + "with fee and with tip (omitempty)", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr, addr), }, } for i, tc := range tests { - got := string(StdSignBytes(tc.args.chainID, tc.args.accnum, tc.args.sequence, tc.args.timeoutHeight, tc.args.fee, tc.args.msgs, tc.args.memo)) - require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i) + tc := tc + t.Run(tc.name, func(t *testing.T) { + got := string(StdSignBytes(tc.args.chainID, tc.args.accnum, tc.args.sequence, tc.args.timeoutHeight, tc.args.fee, tc.args.msgs, tc.args.memo, tc.args.tip)) + require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i) + }) } } diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index 52e35705f062..d3b83d5018bb 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -35,6 +35,7 @@ var ( _ client.TxBuilder = &wrapper{} _ middleware.HasExtensionOptionsTx = &wrapper{} _ ExtensionOptionsTxBuilder = &wrapper{} + _ tx.TipTx = &wrapper{} ) // ExtensionOptionsTxBuilder defines a TxBuilder that can also set extensions. @@ -156,6 +157,10 @@ func (w *wrapper) FeeGranter() sdk.AccAddress { return nil } +func (w *wrapper) GetTip() *tx.Tip { + return w.tx.AuthInfo.Tip +} + func (w *wrapper) GetMemo() string { return w.tx.Body.Memo } diff --git a/x/auth/tx/legacy_amino_json.go b/x/auth/tx/legacy_amino_json.go index fe54d3e3e2e2..01274f9f6ed9 100644 --- a/x/auth/tx/legacy_amino_json.go +++ b/x/auth/tx/legacy_amino_json.go @@ -5,7 +5,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - typestx "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -48,32 +47,32 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, } addr := data.Address - if addr == nil { + if addr == "" { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } + tip := protoTx.GetTip() + isTipper := tip != nil && tip.Tipper == addr + // We set a convention that if the tipper signs with LEGACY_AMINO_JSON, then // they sign over empty fees and 0 gas. - var isTipper bool - if addr == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "got empty address in SIGN_MODE_LEGACY_AMINO_JSON handler") - } - if tipTx, ok := tx.(typestx.TipTx); ok && tipTx.GetTip() != nil { - isTipper = tipTx.GetTip().Tipper == addr.String() - } - if isTipper { return legacytx.StdSignBytes( data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), // The tipper signs over 0 fee and 0 gas, no feepayer, no feegranter by convention. legacytx.StdFee{}, - tx.GetMsgs(), protoTx.GetMemo(), + tx.GetMsgs(), protoTx.GetMemo(), tip, ), nil } return legacytx.StdSignBytes( data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(), - legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas(), Payer: protoTx.FeePayer().String(), Granter: protoTx.FeeGranter().String()}, - tx.GetMsgs(), protoTx.GetMemo(), + legacytx.StdFee{ + Amount: protoTx.GetFee(), + Gas: protoTx.GetGas(), + Payer: protoTx.tx.AuthInfo.Fee.Payer, + Granter: protoTx.tx.AuthInfo.Fee.Granter, + }, + tx.GetMsgs(), protoTx.GetMemo(), tip, ), nil } diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 540b3b464761..a859ea1d64f9 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -8,6 +8,7 @@ import ( cdctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -33,35 +34,93 @@ func buildTx(t *testing.T, bldr *wrapper) { } func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { - bldr := newBuilder() - buildTx(t, bldr) - tx := bldr.GetTx() - var ( - chainId = "test-chain" - accNum uint64 = 7 - seqNum uint64 = 7 + chainId = "test-chain" + accNum uint64 = 7 + seqNum uint64 = 7 + tip *tx.Tip = &tx.Tip{Tipper: addr1.String(), Amount: coins} ) + testcases := []struct { + name string + signer string + malleate func(*wrapper) + expectedSignBz []byte + }{ + { + "signer which is also fee payer (no tips)", addr1.String(), + func(w *wrapper) {}, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, nil), + }, + { + "signer which is also fee payer (with tips)", addr2.String(), + func(w *wrapper) { w.SetTip(tip) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, tip), + }, + { + "explicit fee payer", addr1.String(), + func(w *wrapper) { w.SetFeePayer(addr2) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String()}, []sdk.Msg{msg}, memo, nil), + }, + { + "explicit fee granter", addr1.String(), + func(w *wrapper) { w.SetFeeGranter(addr2) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Granter: addr2.String()}, []sdk.Msg{msg}, memo, nil), + }, + { + "explicit fee payer and feegranter", addr1.String(), + func(w *wrapper) { + w.SetFeePayer(addr2) + w.SetFeeGranter(addr2) + }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String(), Granter: addr2.String()}, []sdk.Msg{msg}, memo, tip), + }, + { + "signer which is also tipper", addr1.String(), + func(w *wrapper) { w.SetTip(tip) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{}, []sdk.Msg{msg}, memo, tip), + }, + { + "signer which is not tipper", addr2.String(), + func(w *wrapper) { w.SetTip(tip) }, + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, tip), + }, + } + handler := signModeLegacyAminoJSONHandler{} + for _, tc := range testcases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + bldr := newBuilder() + buildTx(t, bldr) + tx := bldr.GetTx() + tc.malleate(bldr) + + signingData := signing.SignerData{ + Address: tc.signer, + ChainID: chainId, + AccountNumber: accNum, + Sequence: seqNum, + } + signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + require.NoError(t, err) + + require.Equal(t, tc.expectedSignBz, signBz) + }) + } + + bldr := newBuilder() + buildTx(t, bldr) + tx := bldr.GetTx() signingData := signing.SignerData{ Address: addr1.String(), ChainID: chainId, AccountNumber: accNum, Sequence: seqNum, } - signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) - require.NoError(t, err) - - expectedSignBz := legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{ - Amount: coins, - Gas: gas, - }, []sdk.Msg{msg}, memo) - - require.Equal(t, expectedSignBz, signBz) // expect error with wrong sign mode - _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx) + _, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx) require.Error(t, err) // expect error with extension options @@ -71,7 +130,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { require.NoError(t, err) bldr.tx.Body.ExtensionOptions = []*cdctypes.Any{any} tx = bldr.GetTx() - signBz, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.Error(t, err) // expect error with non-critical extension options @@ -79,8 +138,9 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { buildTx(t, bldr) bldr.tx.Body.NonCriticalExtensionOptions = []*cdctypes.Any{any} tx = bldr.GetTx() - signBz, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) + _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.Error(t, err) + } func TestLegacyAminoJSONHandler_DefaultMode(t *testing.T) { From 892bff453518ecdecf2c6426753be843f84f991e Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 15:40:34 +0200 Subject: [PATCH 19/40] Rename tests --- x/auth/migrations/legacytx/stdtx_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 850c74d3b318..19a01b327a27 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -91,7 +91,7 @@ func TestStdSignBytes(t *testing.T) { want string }{ { - "with timeout height", + "with timeout height (omitempty)", args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","timeout_height":"10"}`, addr), }, @@ -131,10 +131,15 @@ func TestStdSignBytes(t *testing.T) { fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr), }, { - "with fee and with tip (omitempty)", + "with fee and with tip", args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr, addr), }, + { + "with empty tip (but not nil)", + args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", &tx.Tip{}}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[],"tipper":""}}`, addr), + }, } for i, tc := range tests { tc := tc From 2dd883c9ca25cec8b26872ddd38ef10c730dc47e Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 15:43:23 +0200 Subject: [PATCH 20/40] Add more tests --- x/auth/migrations/legacytx/stdtx_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 19a01b327a27..7712f8ff6ba1 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -91,12 +91,12 @@ func TestStdSignBytes(t *testing.T) { want string }{ { - "with timeout height (omitempty)", + "with timeout height", args{"1234", 3, 6, 10, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","timeout_height":"10"}`, addr), }, { - "no timeout height", + "no timeout height (omitempty)", args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), }, @@ -106,20 +106,25 @@ func TestStdSignBytes(t *testing.T) { fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), }, { - "no fee payer and fee granter (omitempty)", + "no fee payer and fee granter (both omitempty)", args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr), }, { - "no fee payer (omitempty)", + "with fee granter, no fee payer (omitempty)", args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), }, { - "no fee granter (omitempty)", + "with fee payer, no fee granter (omitempty)", args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), }, + { + "with fee payer and fee granter", + args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String(), Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr, addr), + }, { "no tip (omitempty)", args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, From 07ef3e20b8db02e70c6f5922cde5b6ee55e42551 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 13 Oct 2021 16:02:43 +0200 Subject: [PATCH 21/40] Empty tip test --- x/auth/migrations/legacytx/stdsign.go | 4 ++++ x/auth/migrations/legacytx/stdtx_test.go | 6 +++--- x/auth/signing/verify_test.go | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/x/auth/migrations/legacytx/stdsign.go b/x/auth/migrations/legacytx/stdsign.go index 7eb5f0349c7f..9467ee8027c8 100644 --- a/x/auth/migrations/legacytx/stdsign.go +++ b/x/auth/migrations/legacytx/stdsign.go @@ -65,6 +65,10 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, var stdTip *StdTip if tip != nil { + if tip.Tipper == "" { + panic(fmt.Errorf("tipper cannot be empty")) + } + stdTip = &StdTip{Amount: tip.Amount, Tipper: tip.Tipper} } diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 7712f8ff6ba1..baee8786cd19 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -141,9 +141,9 @@ func TestStdSignBytes(t *testing.T) { fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr, addr), }, { - "with empty tip (but not nil)", - args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", &tx.Tip{}}, - fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[],"tipper":""}}`, addr), + "with empty tip (but not nil), tipper cannot be empty", + args{"1234", 3, 6, 0, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", &tx.Tip{Tipper: addr.String()}}, + fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[],"tipper":"%s"}}`, addr, addr), }, } for i, tc := range tests { diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index f1984a7f7e12..c36f2e2319a2 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -54,7 +54,7 @@ func TestVerifySignature(t *testing.T) { AccountNumber: acc.GetAccountNumber(), Sequence: acc.GetSequence(), } - signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo) + signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil) signature, err := priv.Sign(signBytes) require.NoError(t, err) @@ -72,7 +72,7 @@ func TestVerifySignature(t *testing.T) { multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet) multisignature := multisig.NewMultisig(2) msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)} - multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo) + multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil) sig1, err := priv.Sign(multiSignBytes) require.NoError(t, err) From b7a1fc11735c630cf1bdf4ca7594c99314fb7a96 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:50:58 +0200 Subject: [PATCH 22/40] feat: Add Tips middleware --- CHANGELOG.md | 1 + client/tx_config.go | 1 + x/auth/middleware/middleware.go | 2 + x/auth/middleware/middleware_test.go | 24 +- x/auth/middleware/testutil_test.go | 19 +- x/auth/middleware/tips.go | 251 ++++++++++++++++++ x/auth/middleware/tips_test.go | 273 ++++++++++++++++++++ x/auth/migrations/legacytx/stdtx.go | 5 + x/auth/migrations/legacytx/stdtx_builder.go | 3 + x/auth/signing/sig_verifiable_tx.go | 2 + x/auth/types/expected_keepers.go | 1 + 11 files changed, 561 insertions(+), 21 deletions(-) create mode 100644 x/auth/middleware/tips.go create mode 100644 x/auth/middleware/tips_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index dcb7f0ea9130..d07a6e5c7e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#9837](https://github.com/cosmos/cosmos-sdk/issues/9837) `--generate-only` flag will accept the keyname now. * [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. +* [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) Add `SignModeTxMiddleware` for checking sign modes and `TipsTxMiddleware` for transferring tips. ### API Breaking Changes diff --git a/client/tx_config.go b/client/tx_config.go index c9db30ff0d7d..941b16218667 100644 --- a/client/tx_config.go +++ b/client/tx_config.go @@ -44,6 +44,7 @@ type ( SetGasLimit(limit uint64) SetTip(tip *tx.Tip) SetTimeoutHeight(height uint64) + SetFeePayer(feePayer sdk.AccAddress) SetFeeGranter(feeGranter sdk.AccAddress) } ) diff --git a/x/auth/middleware/middleware.go b/x/auth/middleware/middleware.go index 60820bb46cc5..f75f5641a42a 100644 --- a/x/auth/middleware/middleware.go +++ b/x/auth/middleware/middleware.go @@ -92,7 +92,9 @@ func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) { SetPubKeyMiddleware(options.AccountKeeper), ValidateSigCountMiddleware(options.AccountKeeper), SigGasConsumeMiddleware(options.AccountKeeper, sigGasConsumer), + SignModeTxMiddleware, SigVerificationMiddleware(options.AccountKeeper, options.SignModeHandler), + NewTipsTxMiddleware(options.BankKeeper), IncrementSequenceMiddleware(options.AccountKeeper), ), nil } diff --git a/x/auth/middleware/middleware_test.go b/x/auth/middleware/middleware_test.go index e3b04983b6f5..d88e5cc6c1da 100644 --- a/x/auth/middleware/middleware_test.go +++ b/x/auth/middleware/middleware_test.go @@ -23,13 +23,15 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +var testCoins = sdk.Coins{sdk.NewInt64Coin("atom", 10000000)} + // Test that simulate transaction accurately estimates gas cost func (s *MWTestSuite) TestSimulateGasCost() { ctx := s.SetupTest(false) // reset txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 3) + accounts := s.createTestAccounts(ctx, 3, testCoins) msgs := []sdk.Msg{ testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()), testdata.NewTestMsg(accounts[2].acc.GetAddress(), accounts[0].acc.GetAddress()), @@ -166,7 +168,7 @@ func (s *MWTestSuite) TestTxHandlerAccountNumbers() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 2) + accounts := s.createTestAccounts(ctx, 2, testCoins) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() @@ -248,7 +250,7 @@ func (s *MWTestSuite) TestTxHandlerAccountNumbersAtBlockHeightZero() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 2) + accounts := s.createTestAccounts(ctx, 2, testCoins) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() @@ -331,7 +333,7 @@ func (s *MWTestSuite) TestTxHandlerSequences() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 3) + accounts := s.createTestAccounts(ctx, 3, testCoins) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() @@ -524,7 +526,7 @@ func (s *MWTestSuite) TestTxHandlerMemoGas() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 1) + accounts := s.createTestAccounts(ctx, 1, testCoins) msgs := []sdk.Msg{testdata.NewTestMsg(accounts[0].acc.GetAddress())} privs, accNums, accSeqs := []cryptotypes.PrivKey{accounts[0].priv}, []uint64{0}, []uint64{0} @@ -594,7 +596,7 @@ func (s *MWTestSuite) TestTxHandlerMultiSigner() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 3) + accounts := s.createTestAccounts(ctx, 3, testCoins) msg1 := testdata.NewTestMsg(accounts[0].acc.GetAddress(), accounts[1].acc.GetAddress()) msg2 := testdata.NewTestMsg(accounts[2].acc.GetAddress(), accounts[0].acc.GetAddress()) msg3 := testdata.NewTestMsg(accounts[1].acc.GetAddress(), accounts[2].acc.GetAddress()) @@ -667,7 +669,7 @@ func (s *MWTestSuite) TestTxHandlerBadSignBytes() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 2) + accounts := s.createTestAccounts(ctx, 2, testCoins) msg0 := testdata.NewTestMsg(accounts[0].acc.GetAddress()) // Variable data per test case @@ -793,7 +795,7 @@ func (s *MWTestSuite) TestTxHandlerSetPubKey() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 2) + accounts := s.createTestAccounts(ctx, 2, testCoins) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() @@ -971,7 +973,7 @@ func (s *MWTestSuite) TestTxHandlerSigLimitExceeded() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 8) + accounts := s.createTestAccounts(ctx, 8, testCoins) var addrs []sdk.AccAddress var privs []cryptotypes.PrivKey for i := 0; i < 8; i++ { @@ -1029,7 +1031,7 @@ func (s *MWTestSuite) TestCustomSignatureVerificationGasConsumer() { s.Require().NoError(err) // Same data for every test cases - accounts := s.createTestAccounts(ctx, 1) + accounts := s.createTestAccounts(ctx, 1, testCoins) txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) txBuilder.SetGasLimit(testdata.NewTestGasLimit()) txBuilder.SetMsgs(testdata.NewTestMsg(accounts[0].acc.GetAddress())) @@ -1073,7 +1075,7 @@ func (s *MWTestSuite) TestTxHandlerReCheck() { txBuilder := s.clientCtx.TxConfig.NewTxBuilder() // Same data for every test cases - accounts := s.createTestAccounts(ctx, 1) + accounts := s.createTestAccounts(ctx, 1, testCoins) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() diff --git a/x/auth/middleware/testutil_test.go b/x/auth/middleware/testutil_test.go index 130b1bbde9be..22825915b098 100644 --- a/x/auth/middleware/testutil_test.go +++ b/x/auth/middleware/testutil_test.go @@ -26,8 +26,9 @@ import ( // testAccount represents an account used in the tests in x/auth/middleware. type testAccount struct { - acc authtypes.AccountI - priv cryptotypes.PrivKey + acc authtypes.AccountI + priv cryptotypes.PrivKey + accNum uint64 } // MWTestSuite is a test suite to be used with middleware tests. @@ -89,25 +90,23 @@ func (s *MWTestSuite) SetupTest(isCheckTx bool) sdk.Context { // createTestAccounts creates `numAccs` accounts, and return all relevant // information about them including their private keys. -func (s *MWTestSuite) createTestAccounts(ctx sdk.Context, numAccs int) []testAccount { +func (s *MWTestSuite) createTestAccounts(ctx sdk.Context, numAccs int, coins sdk.Coins) []testAccount { var accounts []testAccount for i := 0; i < numAccs; i++ { priv, _, addr := testdata.KeyTestPubAddr() acc := s.app.AccountKeeper.NewAccountWithAddress(ctx, addr) - err := acc.SetAccountNumber(uint64(i)) + accNum := uint64(i) + err := acc.SetAccountNumber(accNum) s.Require().NoError(err) s.app.AccountKeeper.SetAccount(ctx, acc) - someCoins := sdk.Coins{ - sdk.NewInt64Coin("atom", 10000000), - } - err = s.app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, someCoins) + err = s.app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, coins) s.Require().NoError(err) - err = s.app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, someCoins) + err = s.app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins) s.Require().NoError(err) - accounts = append(accounts, testAccount{acc, priv}) + accounts = append(accounts, testAccount{acc, priv, accNum}) } return accounts diff --git a/x/auth/middleware/tips.go b/x/auth/middleware/tips.go new file mode 100644 index 000000000000..580c42b08380 --- /dev/null +++ b/x/auth/middleware/tips.go @@ -0,0 +1,251 @@ +package middleware + +import ( + "context" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +type tipsTxHandler struct { + next tx.Handler + bankKeeper types.BankKeeper +} + +// NewTipsTxMiddleware returns a new middleware for handling meta-transactions +// with tips. +func NewTipsTxMiddleware(bankKeeper types.BankKeeper) tx.Middleware { + return func(txh tx.Handler) tx.Handler { + return tipsTxHandler{txh, bankKeeper} + } +} + +var _ tx.Handler = tipsTxHandler{} + +// CheckTx implements tx.Handler.CheckTx. +func (txh tipsTxHandler) CheckTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { + res, err := txh.next.CheckTx(ctx, sdkTx, req) + if err != nil { + return abci.ResponseCheckTx{}, err + } + + tipTx, ok := sdkTx.(tx.TipTx) + if !ok || tipTx.GetTip() == nil { + return res, err + } + + if err := txh.transferTip(ctx, tipTx); err != nil { + return abci.ResponseCheckTx{}, err + } + + return res, err +} + +// DeliverTx implements tx.Handler.DeliverTx. +func (txh tipsTxHandler) DeliverTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestDeliverTx) (abci.ResponseDeliverTx, error) { + res, err := txh.next.DeliverTx(ctx, sdkTx, req) + if err != nil { + return abci.ResponseDeliverTx{}, err + } + + tipTx, ok := sdkTx.(tx.TipTx) + if !ok || tipTx.GetTip() == nil { + return res, err + } + + if err := txh.transferTip(ctx, tipTx); err != nil { + return abci.ResponseDeliverTx{}, err + } + + return res, err +} + +// SimulateTx implements tx.Handler.SimulateTx method. +func (txh tipsTxHandler) SimulateTx(ctx context.Context, sdkTx sdk.Tx, req tx.RequestSimulateTx) (tx.ResponseSimulateTx, error) { + res, err := txh.next.SimulateTx(ctx, sdkTx, req) + if err != nil { + return tx.ResponseSimulateTx{}, err + } + + tipTx, ok := sdkTx.(tx.TipTx) + if !ok || tipTx.GetTip() == nil { + return res, err + } + + if err := txh.transferTip(ctx, tipTx); err != nil { + return tx.ResponseSimulateTx{}, err + } + + return res, err +} + +// transferTip transfers the tip from the tipper to the fee payer. +func (txh tipsTxHandler) transferTip(ctx context.Context, tipTx tx.TipTx) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + tipper, err := sdk.AccAddressFromBech32(tipTx.GetTip().Tipper) + if err != nil { + return err + } + + return txh.bankKeeper.SendCoins(sdkCtx, tipper, tipTx.FeePayer(), tipTx.GetTip().Amount) +} + +type signModeTxHandler struct { + next tx.Handler +} + +// SignModeTxMiddleware returns a new middleware that checks that +// all signatures in the tx have correct sign modes. +// Namely: +// - fee payer should sign over fees, +// - tipper should signer over tips. +func SignModeTxMiddleware(txh tx.Handler) tx.Handler { + return signModeTxHandler{txh} +} + +var _ tx.Handler = signModeTxHandler{} + +// CheckTx implements tx.Handler.CheckTx. +func (txh signModeTxHandler) CheckTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { + if err := checkSignMode(sdkTx); err != nil { + return abci.ResponseCheckTx{}, err + } + + return txh.next.CheckTx(ctx, sdkTx, req) +} + +// DeliverTx implements tx.Handler.DeliverTx. +func (txh signModeTxHandler) DeliverTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestDeliverTx) (abci.ResponseDeliverTx, error) { + if err := checkSignMode(sdkTx); err != nil { + return abci.ResponseDeliverTx{}, err + } + + return txh.next.DeliverTx(ctx, sdkTx, req) +} + +// SimulateTx implements tx.Handler.SimulateTx method. +func (txh signModeTxHandler) SimulateTx(ctx context.Context, sdkTx sdk.Tx, req tx.RequestSimulateTx) (tx.ResponseSimulateTx, error) { + if err := checkSignMode(sdkTx); err != nil { + return tx.ResponseSimulateTx{}, err + } + + return txh.next.SimulateTx(ctx, sdkTx, req) +} + +// checkSignMode checks that all signatures in the tx have correct sign modes. +// Namely: +// - fee payer should sign over fees, +// - tipper should signer over tips. +func checkSignMode(sdkTx sdk.Tx) error { + tipTx, ok := sdkTx.(tx.TipTx) + if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrTxDecode, "tx must be a TipTx, got %T", sdkTx) + } + feePayer := tipTx.FeePayer() + var tipper string + if tip := tipTx.GetTip(); tip != nil { + tipper = tipTx.GetTip().Tipper + } + + sigTx, ok := sdkTx.(authsigning.SigVerifiableTx) + if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrTxDecode, "tx must be a SigVerifiableTx, got %T", sdkTx) + } + sigsV2, err := sigTx.GetSignaturesV2() + if err != nil { + return err + } + + for _, sig := range sigsV2 { + addr := sdk.AccAddress(sig.PubKey.Address()) + + // Make sure the feePayer signs over the Fee. + if addr.Equals(feePayer) { + if err := checkFeeSigner(addr, sig.Data); err != nil { + return err + } + } + + // Make sure the tipper signs over the Tip. + if addr.String() == tipper { + if err := checkTipSigner(addr, sig.Data); err != nil { + return err + } + } + } + + return nil +} + +// checkFeeSigner checks whether a signature has signed over Fees. +func checkFeeSigner(addr sdk.AccAddress, sigData signing.SignatureData) error { + if err := checkCorrectSignModes(addr, sigData, []signing.SignMode{ + signing.SignMode_SIGN_MODE_DIRECT, + signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + }, "fee payer"); err != nil { + return err + } + + return nil +} + +// checkTipSigner checks whether a signature has signed over Tips. +func checkTipSigner(addr sdk.AccAddress, sigData signing.SignatureData) error { + if err := checkCorrectSignModes(addr, sigData, []signing.SignMode{ + signing.SignMode_SIGN_MODE_DIRECT, + signing.SignMode_SIGN_MODE_DIRECT_AUX, + signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + }, "tipper"); err != nil { + return err + } + + return nil +} + +// checkCorrectSignModes checks that all signatures are one of the allowed +// sign modes defined in `allowedSignModes`. +// For multi-signatures, check recursively. +func checkCorrectSignModes( + addr sdk.AccAddress, + sigData signing.SignatureData, + allowedSignModes []signing.SignMode, + errString string, +) error { + switch sigData := sigData.(type) { + case *signing.SingleSignatureData: + { + if !arrayIncludes(allowedSignModes, sigData.SignMode) { + return sdkerrors.ErrUnauthorized.Wrapf("invalid sign mode for %s %s, got %s", errString, addr, sigData.SignMode) + } + } + case *signing.MultiSignatureData: + { + for _, s := range sigData.Signatures { + err := checkCorrectSignModes(addr, s, allowedSignModes, errString) + if err != nil { + return err + } + } + } + default: + return sdkerrors.ErrInvalidType.Wrapf("got unexpected SignatureData %T", sigData) + } + + return nil +} + +func arrayIncludes(sms []signing.SignMode, sm signing.SignMode) bool { + for _, x := range sms { + if x == sm { + return true + } + } + + return false +} diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go new file mode 100644 index 000000000000..d23f15e3ea2e --- /dev/null +++ b/x/auth/middleware/tips_test.go @@ -0,0 +1,273 @@ +package middleware_test + +import ( + "fmt" + "time" + + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/middleware" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +var initialRegens = sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(1000))) +var initialAtoms = sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(1000))) + +// setupMetaTxAccts sets up 2 accounts: +// - tipper has 1000 regens +// - feePayer has 1000 atoms and 1000 regens +func (s *MWTestSuite) setupMetaTxAccts(ctx sdk.Context) (sdk.Context, []testAccount) { + accts := s.createTestAccounts(ctx, 2, initialRegens) + feePayer := accts[1] + err := s.app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, initialAtoms) + s.Require().NoError(err) + err = s.app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, feePayer.acc.GetAddress(), initialAtoms) + s.Require().NoError(err) + + // Create dummy proposal for tipper to vote on. + prop, err := govtypes.NewProposal(govtypes.NewTextProposal("foo", "bar"), 1, time.Now(), time.Now().Add(time.Hour)) + s.Require().NoError(err) + s.app.GovKeeper.SetProposal(ctx, prop) + s.app.GovKeeper.ActivateVotingPeriod(ctx, prop) + + // Move to next block to commit previous data to state. + s.app.EndBlock(abci.RequestEndBlock{Height: 1}) + s.app.Commit() + s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 2}}) + ctx = ctx.WithBlockHeight(2) + + return ctx, accts +} + +func (s *MWTestSuite) TestSignModes() { + ctx := s.SetupTest(false) // reset + ctx, accts := s.setupMetaTxAccts(ctx) + tipper, feePayer := accts[0], accts[1] + msg := govtypes.NewMsgVote(tipper.acc.GetAddress(), 1, govtypes.OptionYes) + + txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.SignModeTxMiddleware) + + testcases := []struct { + tipperSignMode signing.SignMode + feePayerSignMode signing.SignMode + expErr bool + }{ + {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_DIRECT, false}, + {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, + {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, + {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_DIRECT, false}, + {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, + {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, + {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_DIRECT, false}, + {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, + {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, + } + + for _, tc := range testcases { + tc := tc + s.Run(fmt.Sprintf("tipper=%s, feepayer=%s", tc.tipperSignMode, tc.feePayerSignMode), func() { + tipperTxBuilder := s.mkTipperTxBuilder(tipper.priv, msg, initialRegens, tc.tipperSignMode, tipper.accNum, 0, ctx.ChainID()) + feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, feePayer.priv, tc.feePayerSignMode, tx.Fee{Amount: initialAtoms, GasLimit: 200000}, tipperTxBuilder.GetTx(), feePayer.accNum, 0, ctx.ChainID()) + s.Require().NoError(err) + + _, err = txHandler.DeliverTx(sdk.WrapSDKContext(ctx), feePayerTxBuilder.GetTx(), abci.RequestDeliverTx{}) + if tc.expErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), "invalid sign mode for") + } else { + s.Require().NoError(err) + } + }) + } +} + +func (s *MWTestSuite) TestTips() { + var msg sdk.Msg + _, _, randomAddr := testdata.KeyTestPubAddr() + + testcases := []struct { + name string + msgSigner sdk.AccAddress + tip sdk.Coins + fee sdk.Coins + gasLimit uint64 + expErr bool + expErrStr string + }{ + { + "tipper should be equal to msg signer", + randomAddr, // arbitrary msg signer, not equal to tipper + sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 100000, + true, "pubKey does not match signer address", + }, + { + "wrong tip denom", nil, + sdk.NewCoins(sdk.NewCoin("foobar", sdk.NewInt(1000))), initialAtoms, 100000, + true, "0foobar is smaller than 1000foobar: insufficient funds", + }, + { + "insufficient tip from tipper", nil, + sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 100000, + true, "1000regen is smaller than 5000regen: insufficient funds", + }, + { + "insufficient fees from feePayer", nil, + initialRegens, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(5000))), 100000, + true, "1000atom is smaller than 5000atom: insufficient funds: insufficient funds", + }, + { + "insufficient gas", nil, + initialRegens, initialAtoms, 100, + true, "out of gas in location: ReadFlat; gasWanted: 100, gasUsed: 1000: out of gas", + }, + { + "happy case", nil, + initialRegens, initialAtoms, 100000, + false, "", + }, + } + + for _, tc := range testcases { + tc := tc + s.Run(tc.name, func() { + ctx := s.SetupTest(false) // reset + ctx, accts := s.setupMetaTxAccts(ctx) + tipper, feePayer := accts[0], accts[1] + + voter := tc.msgSigner + if voter == nil { + voter = tipper.acc.GetAddress() // Choose tipper as MsgSigner, unless overwritten by testcase. + } + msg = govtypes.NewMsgVote(voter, 1, govtypes.OptionYes) + + tipperTxBuilder := s.mkTipperTxBuilder(tipper.priv, msg, tc.tip, signing.SignMode_SIGN_MODE_DIRECT_AUX, tipper.accNum, 0, ctx.ChainID()) + feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, feePayer.priv, signing.SignMode_SIGN_MODE_DIRECT, tx.Fee{Amount: tc.fee, GasLimit: tc.gasLimit}, tipperTxBuilder.GetTx(), feePayer.accNum, 0, ctx.ChainID()) + s.Require().NoError(err) + + _, res, err := s.app.SimDeliver(s.clientCtx.TxConfig.TxEncoder(), feePayerTxBuilder.GetTx()) + + if tc.expErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expErrStr) + } else { + s.Require().NoError(err) + s.Require().NotNil(res) + + // Move to next block to commit previous data to state. + s.app.EndBlock(abci.RequestEndBlock{Height: 2}) + s.app.Commit() + s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 3}}) + ctx = ctx.WithBlockHeight(3) + + // Make sure tip is correctly transferred to feepayer, and fee is paid. + expTipperRegens := initialRegens.Sub(tc.tip) + expFeePayerRegens := initialRegens.Add(tc.tip...) + expFeePayerAtoms := initialAtoms.Sub(tc.fee) + s.Require().True(expTipperRegens.AmountOf("regen").Equal(s.app.BankKeeper.GetBalance(ctx, tipper.acc.GetAddress(), "regen").Amount)) + s.Require().True(expFeePayerRegens.AmountOf("regen").Equal(s.app.BankKeeper.GetBalance(ctx, feePayer.acc.GetAddress(), "regen").Amount)) + s.Require().True(expFeePayerAtoms.AmountOf("atom").Equal(s.app.BankKeeper.GetBalance(ctx, feePayer.acc.GetAddress(), "atom").Amount)) + // Make sure MsgVote has been submitted by tipper. + votes := s.app.GovKeeper.GetAllVotes(ctx) + s.Require().Len(votes, 1) + s.Require().Equal(tipper.acc.GetAddress().String(), votes[0].Voter) + } + }) + } +} + +func (s *MWTestSuite) mkTipperTxBuilder( + tipperPriv cryptotypes.PrivKey, msg sdk.Msg, tip sdk.Coins, + signMode signing.SignMode, accNum, accSeq uint64, chainID string, +) client.TxBuilder { + txBuilder := s.clientCtx.TxConfig.NewTxBuilder() + txBuilder.SetTip(&tx.Tip{ + Amount: tip, + Tipper: sdk.AccAddress(tipperPriv.PubKey().Address()).String(), + }) + err := txBuilder.SetMsgs(msg) + s.Require().NoError(err) + + // Call SetSignatures with empty sig to populate AuthInfo. + err = txBuilder.SetSignatures(signing.SignatureV2{ + PubKey: tipperPriv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: signMode, + Signature: nil, + }}) + s.Require().NoError(err) + + // Actually sign the data. + signerData := authsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNum, + Sequence: accSeq, + } + sigV2, err := clienttx.SignWithPrivKey( + signMode, signerData, + txBuilder, tipperPriv, s.clientCtx.TxConfig, accSeq) + s.Require().NoError(err) + + txBuilder.SetSignatures(sigV2) + + return txBuilder +} + +func mkFeePayerTxBuilder( + clientCtx client.Context, + feePayerPriv cryptotypes.PrivKey, signMode signing.SignMode, + fee tx.Fee, tipTx tx.TipTx, accNum, accSeq uint64, chainID string, +) (client.TxBuilder, error) { + txBuilder := clientCtx.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs(tipTx.GetMsgs()...) + if err != nil { + return nil, err + } + txBuilder.SetFeePayer(sdk.AccAddress(feePayerPriv.PubKey().Address())) + txBuilder.SetFeeAmount(fee.Amount) + txBuilder.SetGasLimit(fee.GasLimit) + txBuilder.SetTip(tipTx.GetTip()) + + // Calling SetSignatures with empty sig to populate AuthInfo. + tipperSigsV2, err := tipTx.(authsigning.SigVerifiableTx).GetSignaturesV2() + if err != nil { + return nil, err + } + feePayerSigV2 := signing.SignatureV2{ + PubKey: feePayerPriv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: signMode, + Signature: nil, + }} + sigsV2 := append(tipperSigsV2, feePayerSigV2) + txBuilder.SetSignatures(sigsV2...) + + // Actually sign the data. + signerData := authsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNum, + Sequence: accSeq, + } + feePayerSigV2, err = clienttx.SignWithPrivKey( + signMode, signerData, + txBuilder, feePayerPriv, clientCtx.TxConfig, accSeq) + if err != nil { + return nil, err + } + sigsV2 = append(tipperSigsV2, feePayerSigV2) + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + return txBuilder, nil +} diff --git a/x/auth/migrations/legacytx/stdtx.go b/x/auth/migrations/legacytx/stdtx.go index 68f3b330eae8..33f7328da5e4 100644 --- a/x/auth/migrations/legacytx/stdtx.go +++ b/x/auth/migrations/legacytx/stdtx.go @@ -6,6 +6,7 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx" txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -15,6 +16,7 @@ var ( _ sdk.Tx = (*StdTx)(nil) _ sdk.TxWithMemo = (*StdTx)(nil) _ sdk.FeeTx = (*StdTx)(nil) + _ tx.TipTx = (*StdTx)(nil) _ codectypes.UnpackInterfacesMessage = (*StdTx)(nil) _ codectypes.UnpackInterfacesMessage = (*StdSignature)(nil) @@ -232,6 +234,9 @@ func (tx StdTx) FeeGranter() sdk.AccAddress { return nil } +// GetTip always returns nil for StdTx +func (tx StdTx) GetTip() *tx.Tip { return nil } + func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { for _, m := range tx.Msgs { err := codectypes.UnpackInterfaces(m, unpacker) diff --git a/x/auth/migrations/legacytx/stdtx_builder.go b/x/auth/migrations/legacytx/stdtx_builder.go index af848d13eb8c..1c4e686f26fa 100644 --- a/x/auth/migrations/legacytx/stdtx_builder.go +++ b/x/auth/migrations/legacytx/stdtx_builder.go @@ -71,6 +71,9 @@ func (s *StdTxBuilder) SetTimeoutHeight(height uint64) { s.TimeoutHeight = height } +// SetFeePayer does nothing for stdtx +func (s *StdTxBuilder) SetFeePayer(_ sdk.AccAddress) {} + // SetFeeGranter does nothing for stdtx func (s *StdTxBuilder) SetFeeGranter(_ sdk.AccAddress) {} diff --git a/x/auth/signing/sig_verifiable_tx.go b/x/auth/signing/sig_verifiable_tx.go index 2d8aeb49db9a..698d2ac918cb 100644 --- a/x/auth/signing/sig_verifiable_tx.go +++ b/x/auth/signing/sig_verifiable_tx.go @@ -3,6 +3,7 @@ package signing import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) @@ -22,5 +23,6 @@ type Tx interface { types.TxWithMemo types.FeeTx + tx.TipTx types.TxWithTimeoutHeight } diff --git a/x/auth/types/expected_keepers.go b/x/auth/types/expected_keepers.go index 0ab3f9c4308e..7f242c63fd3a 100644 --- a/x/auth/types/expected_keepers.go +++ b/x/auth/types/expected_keepers.go @@ -6,5 +6,6 @@ import ( // BankKeeper defines the contract needed for supply related APIs (noalias) type BankKeeper interface { + SendCoins(ctx sdk.Context, from, to sdk.AccAddress, amt sdk.Coins) error SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } From 4a83a3f043a5c1748f8cd5c2e956035bbc4313a5 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:56:03 +0200 Subject: [PATCH 23/40] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d07a6e5c7e84..de853fdad855 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Move Baseapp panic recovery into a middleware. * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}`. * [\#10322](https://github.com/cosmos/cosmos-sdk/pull/10322) The `tx.NewTxConfig` function takes a new parameter of type `address.Codec` used to encode and decode addresses. As such, a new field `AddressCdc` has been added to `simapp.EncodingConfig`. +* [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) The `x/auth/signing.Tx` interface now also includes a new `GetTip() *tx.Tip` method for verifying tipped transactions. The `x/auth/types` expected BankKeeper interface now expects the `SendCoins` method too. ### Client Breaking Changes From d5feed548f8bcd0023b2757af60fbc19b409e60f Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 18 Oct 2021 13:00:47 +0200 Subject: [PATCH 24/40] Revert unwanted files --- CHANGELOG.md | 4 ++- client/tx/legacy_test.go | 2 +- server/rosetta/client_online.go | 3 +- server/rosetta/converter_test.go | 3 +- simapp/params/amino.go | 2 -- simapp/params/encoding.go | 2 -- simapp/params/proto.go | 6 +--- {x/auth => types}/address/codec.go | 0 x/auth/address/bech32.go | 47 ------------------------------ x/auth/keeper/bech32_codec.go | 46 +++++++++++++++++++++++++++++ x/auth/keeper/keeper.go | 11 +++---- x/auth/middleware/feegrant_test.go | 3 +- x/auth/middleware/sigverify.go | 6 ++-- x/auth/tx/config.go | 11 +++---- x/auth/tx/direct_aux.go | 5 +--- x/auth/tx/direct_aux_test.go | 6 ++-- 16 files changed, 72 insertions(+), 85 deletions(-) rename {x/auth => types}/address/codec.go (100%) delete mode 100644 x/auth/address/bech32.go create mode 100644 x/auth/keeper/bech32_codec.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ad7b05ee5b..5c98334aa468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10045](https://github.com/cosmos/cosmos-sdk/pull/10045) Revert [#8549](https://github.com/cosmos/cosmos-sdk/pull/8549). Do not route grpc queries through Tendermint. * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. * [\#10024](https://github.com/cosmos/cosmos-sdk/pull/10024) `store/cachekv` performance improvement by reduced growth factor for iterator ranging by using binary searches to find dirty items when unsorted key count >= 1024 +* [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. ### API Breaking Changes @@ -98,9 +99,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Replace `baseapp.SetAnteHandler` with `baseapp.SetTxHandler`. * Move Msg routers from BaseApp to middlewares. * Move Baseapp panic recovery into a middleware. - * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}`. + * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}**`. * (x/gov) [\#10373](https://github.com/cosmos/cosmos-sdk/pull/10373) Removed gov `keeper.{MustMarshal, MustUnmarshal}`. + ### Client Breaking Changes * [\#9879](https://github.com/cosmos/cosmos-sdk/pull/9879) Modify ABCI Queries to use `abci.QueryRequest` Height field if it is non-zero, otherwise continue using context height. diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 94c43301eb07..65949a038fa1 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -61,7 +61,7 @@ type TestSuite struct { func (s *TestSuite) SetupSuite() { encCfg := simapp.MakeTestEncodingConfig() s.encCfg = encCfg - s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes, s.encCfg.AddressCdc) + s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes) s.aminoCfg = legacytx.StdTxConfig{Cdc: encCfg.Amino} } diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index eebaa67e1e9e..ca00a1ff5ac7 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -20,7 +20,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth/address" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" auth "github.com/cosmos/cosmos-sdk/x/auth/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -56,7 +55,7 @@ func NewClient(cfg *Config) (*Client, error) { v = "unknown" } - txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) + txConfig := authtx.NewTxConfig(cfg.Codec, authtx.DefaultSignModes) var supportedOperations []string for _, ii := range cfg.InterfaceRegistry.ListImplementations(sdk.MsgInterfaceProtoName) { diff --git a/server/rosetta/converter_test.go b/server/rosetta/converter_test.go index f7e2b36a46b4..1177d33405df 100644 --- a/server/rosetta/converter_test.go +++ b/server/rosetta/converter_test.go @@ -7,7 +7,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/x/auth/address" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/client" @@ -45,7 +44,7 @@ func (s *ConverterTestSuite) SetupTest() { s.unsignedTxBytes = unsignedTxBytes // instantiate converter cdc, ir := rosetta.MakeCodec() - txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) + txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes) s.c = rosetta.NewConverter(cdc, ir, txConfig) // add utils s.ir = ir diff --git a/simapp/params/amino.go b/simapp/params/amino.go index 39bf4d54e5c5..7ae119f5f3d6 100644 --- a/simapp/params/amino.go +++ b/simapp/params/amino.go @@ -17,10 +17,8 @@ func MakeTestEncodingConfig() EncodingConfig { cdc := codec.NewLegacyAmino() interfaceRegistry := types.NewInterfaceRegistry() marshaler := codec.NewAminoCodec(cdc) - addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ - AddressCdc: addressCdc, InterfaceRegistry: interfaceRegistry, Marshaler: marshaler, TxConfig: legacytx.StdTxConfig{Cdc: cdc}, diff --git a/simapp/params/encoding.go b/simapp/params/encoding.go index edbf0ca0cd2b..8ff9ea04b39b 100644 --- a/simapp/params/encoding.go +++ b/simapp/params/encoding.go @@ -4,13 +4,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/x/auth/address" ) // EncodingConfig specifies the concrete encoding types to use for a given app. // This is provided for compatibility between protobuf and amino implementations. type EncodingConfig struct { - AddressCdc address.Codec InterfaceRegistry types.InterfaceRegistry Codec codec.Codec TxConfig client.TxConfig diff --git a/simapp/params/proto.go b/simapp/params/proto.go index 905eaf1ae06e..2a38fff04008 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -6,8 +6,6 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -19,13 +17,11 @@ func MakeTestEncodingConfig() EncodingConfig { cdc := codec.NewLegacyAmino() interfaceRegistry := types.NewInterfaceRegistry() codec := codec.NewProtoCodec(interfaceRegistry) - addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) return EncodingConfig{ - AddressCdc: addressCdc, InterfaceRegistry: interfaceRegistry, Codec: codec, - TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes, addressCdc), + TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), Amino: cdc, } } diff --git a/x/auth/address/codec.go b/types/address/codec.go similarity index 100% rename from x/auth/address/codec.go rename to types/address/codec.go diff --git a/x/auth/address/bech32.go b/x/auth/address/bech32.go deleted file mode 100644 index b0adde5a69ab..000000000000 --- a/x/auth/address/bech32.go +++ /dev/null @@ -1,47 +0,0 @@ -package address - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/bech32" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// Bech32Codec is a address.Codec based on bech32 encoding. -type Bech32Codec struct { - Bech32Prefix string -} - -var _ Codec = &Bech32Codec{} - -// NewBech32Codec creates a new address.Codec based on bech32 encoding. -func NewBech32Codec(prefix string) Codec { - return Bech32Codec{prefix} -} - -// StringToBytes encodes text to bytes. -func (bc Bech32Codec) StringToBytes(text string) ([]byte, error) { - hrp, bz, err := bech32.DecodeAndConvert(text) - if err != nil { - return nil, err - } - - if hrp != bc.Bech32Prefix { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "hrp does not match bech32Prefix") - } - - if err := sdk.VerifyAddressFormat(bz); err != nil { - return nil, err - } - - return bz, nil -} - -// BytesToString decodes bytes to text. -func (bc Bech32Codec) BytesToString(bz []byte) (string, error) { - text, err := bech32.ConvertAndEncode(bc.Bech32Prefix, bz) - if err != nil { - return "", err - } - - return text, nil -} diff --git a/x/auth/keeper/bech32_codec.go b/x/auth/keeper/bech32_codec.go new file mode 100644 index 000000000000..b107b67de9f4 --- /dev/null +++ b/x/auth/keeper/bech32_codec.go @@ -0,0 +1,46 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/cosmos/cosmos-sdk/types/bech32" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +type bech32Codec struct { + bech32Prefix string +} + +var _ address.Codec = &bech32Codec{} + +func newBech32Codec(prefix string) bech32Codec { + return bech32Codec{prefix} +} + +// StringToBytes encodes text to bytes +func (bc bech32Codec) StringToBytes(text string) ([]byte, error) { + hrp, bz, err := bech32.DecodeAndConvert(text) + if err != nil { + return nil, err + } + + if hrp != bc.bech32Prefix { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "hrp does not match bech32Prefix") + } + + if err := sdk.VerifyAddressFormat(bz); err != nil { + return nil, err + } + + return bz, nil +} + +// BytesToString decodes bytes to text +func (bc bech32Codec) BytesToString(bz []byte) (string, error) { + text, err := bech32.ConvertAndEncode(bc.bech32Prefix, bz) + if err != nil { + return "", err + } + + return text, nil +} diff --git a/x/auth/keeper/keeper.go b/x/auth/keeper/keeper.go index 16a6e83e475b..25592115a3e9 100644 --- a/x/auth/keeper/keeper.go +++ b/x/auth/keeper/keeper.go @@ -9,10 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/codec" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -86,7 +87,7 @@ func NewAccountKeeper( permAddrs[name] = types.NewPermissionsForAddress(name, perms) } - bech32Codec := address.NewBech32Codec(bech32Prefix) + bech32Codec := newBech32Codec(bech32Prefix) return AccountKeeper{ key: key, @@ -246,10 +247,10 @@ func (ak AccountKeeper) GetCodec() codec.BinaryCodec { return ak.cdc } // add getter for bech32Prefix func (ak AccountKeeper) getBech32Prefix() (string, error) { - bech32Codec, ok := ak.addressCdc.(address.Bech32Codec) + bech32Codec, ok := ak.addressCdc.(bech32Codec) if !ok { return "", errors.New("unable cast addressCdc to bech32Codec") } - return bech32Codec.Bech32Prefix, nil + return bech32Codec.bech32Prefix, nil } diff --git a/x/auth/middleware/feegrant_test.go b/x/auth/middleware/feegrant_test.go index a0e719ab9df7..c76b3ec825e4 100644 --- a/x/auth/middleware/feegrant_test.go +++ b/x/auth/middleware/feegrant_test.go @@ -16,7 +16,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/middleware" authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/tx" @@ -29,7 +28,7 @@ func (s *MWTestSuite) TestDeductFeesNoDelegation() { ctx := s.SetupTest(false) // setup app := s.app - protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(app.InterfaceRegistry()), tx.DefaultSignModes, address.NewBech32Codec(sdk.Bech32MainPrefix)) + protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(app.InterfaceRegistry()), tx.DefaultSignModes) txHandler := middleware.ComposeMiddlewares( noopTxHandler{}, diff --git a/x/auth/middleware/sigverify.go b/x/auth/middleware/sigverify.go index 0d5796d6346e..0613b835c98f 100644 --- a/x/auth/middleware/sigverify.go +++ b/x/auth/middleware/sigverify.go @@ -429,13 +429,13 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { } } -func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, sdkTx sdk.Tx, isReCheckTx, simulate bool) error { +func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, tx sdk.Tx, isReCheckTx, simulate bool) error { sdkCtx := sdk.UnwrapSDKContext(ctx) // no need to verify signatures on recheck tx if isReCheckTx { return nil } - sigTx, ok := sdkTx.(authsigning.SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } @@ -491,7 +491,7 @@ func (svm sigVerificationTxHandler) sigVerify(ctx context.Context, sdkTx sdk.Tx, } if !simulate { - err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svm.signModeHandler, sdkTx) + err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svm.signModeHandler, tx) if err != nil { var errMsg string if OnlyLegacyAminoSigners(sig.Data) { diff --git a/x/auth/tx/config.go b/x/auth/tx/config.go index 0b57b03092b2..8402423dbf77 100644 --- a/x/auth/tx/config.go +++ b/x/auth/tx/config.go @@ -3,11 +3,12 @@ package tx import ( "fmt" - "github.com/cosmos/cosmos-sdk/client" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/codec" + + "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -22,9 +23,9 @@ type config struct { // NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and sign modes. The // first enabled sign mode will become the default sign mode. -func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, addressCdc address.Codec) client.TxConfig { +func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode) client.TxConfig { return &config{ - handler: makeSignModeHandler(enabledSignModes, addressCdc), + handler: makeSignModeHandler(enabledSignModes), decoder: DefaultTxDecoder(protoCodec), encoder: DefaultTxEncoder(), jsonDecoder: DefaultJSONTxDecoder(protoCodec), diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 2144474270dc..b5cf427a1841 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -7,16 +7,13 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" types "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) var _ signing.SignModeHandler = signModeDirectAuxHandler{} // signModeDirectAuxHandler defines the SIGN_MODE_DIRECT_AUX SignModeHandler -type signModeDirectAuxHandler struct { - addressCdc address.Codec -} +type signModeDirectAuxHandler struct{} // DefaultMode implements SignModeHandler.DefaultMode func (signModeDirectAuxHandler) DefaultMode() signingtypes.SignMode { diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index 90bcb2665707..df7460c5ba78 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -12,7 +12,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/address" "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -21,9 +20,8 @@ func TestDirectAuxHandler(t *testing.T) { interfaceRegistry := codectypes.NewInterfaceRegistry() interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) - addressCdc := address.NewBech32Codec(sdk.Bech32MainPrefix) - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}, addressCdc) + txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}) txBuilder := txConfig.NewTxBuilder() memo := "sometestmemo" @@ -61,7 +59,7 @@ func TestDirectAuxHandler(t *testing.T) { SignerIndex: 0, } - modeHandler := signModeDirectAuxHandler{addressCdc} + modeHandler := signModeDirectAuxHandler{} signBytes, err := modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, signingData, txBuilder.GetTx()) require.NoError(t, err) require.NotNil(t, signBytes) From 0071f3caee8456ca2847ffaa29d083e926c8149c Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 18 Oct 2021 13:04:14 +0200 Subject: [PATCH 25/40] Less line diff --- server/rosetta/client_online.go | 13 +++++++++---- simapp/params/amino.go | 1 - x/auth/tx/direct_aux.go | 2 +- x/auth/tx/legacy_amino_json_test.go | 1 - 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index ca00a1ff5ac7..0a34b8b1a878 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -8,21 +8,26 @@ import ( "strconv" "time" - rosettatypes "github.com/coinbase/rosetta-sdk-go/types" + "github.com/cosmos/cosmos-sdk/version" + abcitypes "github.com/tendermint/tendermint/abci/types" - tmrpc "github.com/tendermint/tendermint/rpc/client" + + rosettatypes "github.com/coinbase/rosetta-sdk-go/types" + "google.golang.org/grpc/metadata" + "github.com/tendermint/tendermint/rpc/client/http" "google.golang.org/grpc" - "google.golang.org/grpc/metadata" crgerrs "github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors" crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types" + sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" - "github.com/cosmos/cosmos-sdk/version" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" auth "github.com/cosmos/cosmos-sdk/x/auth/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" + + tmrpc "github.com/tendermint/tendermint/rpc/client" ) // interface assertion diff --git a/simapp/params/amino.go b/simapp/params/amino.go index 7ae119f5f3d6..cdf86d0ea2e0 100644 --- a/simapp/params/amino.go +++ b/simapp/params/amino.go @@ -5,7 +5,6 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" ) diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index b5cf427a1841..71a3fd5c0426 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -26,7 +26,7 @@ func (signModeDirectAuxHandler) Modes() []signingtypes.SignMode { } // GetSignBytes implements SignModeHandler.GetSignBytes -func (h signModeDirectAuxHandler) GetSignBytes( +func (signModeDirectAuxHandler) GetSignBytes( mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx, ) ([]byte, error) { diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 1c47aa2cd724..1cb23c33167f 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -141,7 +141,6 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { tx = bldr.GetTx() _, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx) require.Error(t, err) - } func TestLegacyAminoJSONHandler_DefaultMode(t *testing.T) { From df19e585f2fb80ab6db5f1ee23b43a39f8129e93 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 18 Oct 2021 13:29:41 +0200 Subject: [PATCH 26/40] fix test --- x/auth/tx/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/tx/config_test.go b/x/auth/tx/config_test.go index 3d15863426f1..b20cf1ce4e85 100644 --- a/x/auth/tx/config_test.go +++ b/x/auth/tx/config_test.go @@ -18,5 +18,5 @@ func TestGenerator(t *testing.T) { std.RegisterInterfaces(interfaceRegistry) interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) protoCodec := codec.NewProtoCodec(interfaceRegistry) - suite.Run(t, testutil.NewTxConfigTestSuite(NewTxConfig(protoCodec, DefaultSignModes, nil))) + suite.Run(t, testutil.NewTxConfigTestSuite(NewTxConfig(protoCodec, DefaultSignModes))) } From 6c069d5f495080c685bde197f7ffe35e0b742ca7 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 18 Oct 2021 14:00:09 +0200 Subject: [PATCH 27/40] fix another test --- x/auth/tx/direct_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/tx/direct_test.go b/x/auth/tx/direct_test.go index faf6dcaf2949..418ab56e11a7 100644 --- a/x/auth/tx/direct_test.go +++ b/x/auth/tx/direct_test.go @@ -21,7 +21,7 @@ func TestDirectModeHandler(t *testing.T) { interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) - txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT}, nil) + txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT}) txBuilder := txConfig.NewTxBuilder() memo := "sometestmemo" From 72163708875de4d7d26d6bdb5c24e4cd49f3d322 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 18 Oct 2021 14:26:35 +0200 Subject: [PATCH 28/40] Fix test --- x/auth/tx/legacy_amino_json_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 1cb23c33167f..95d641619cfd 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -73,7 +73,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { w.SetFeePayer(addr2) w.SetFeeGranter(addr2) }, - legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String(), Granter: addr2.String()}, []sdk.Msg{msg}, memo, tip), + legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Payer: addr2.String(), Granter: addr2.String()}, []sdk.Msg{msg}, memo, nil), }, { "signer which is also tipper", addr1.String(), From 0fa4bc07cbbb8691812c25aae9d68bc645be857c Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Tue, 19 Oct 2021 13:32:07 +0200 Subject: [PATCH 29/40] Update x/auth/migrations/legacytx/stdtx_test.go Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> --- x/auth/migrations/legacytx/stdtx_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index baee8786cd19..6bb7c353bf91 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -131,7 +131,7 @@ func TestStdSignBytes(t *testing.T) { fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), }, { - "no fee, with tip (omitempty)", + "no fee, with tip", args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[["%s"]],"sequence":"6","tip":{"amount":[{"amount":"150","denom":"tiptoken"}],"tipper":"%s"}}`, addr, addr), }, From 6058b7dfa472e8b82439add66d66344070a0f3cc Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 19 Oct 2021 14:51:28 +0200 Subject: [PATCH 30/40] Fix tests --- x/auth/middleware/testutil_test.go | 3 +-- x/auth/middleware/tips_test.go | 11 ++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/x/auth/middleware/testutil_test.go b/x/auth/middleware/testutil_test.go index 853b200c3c38..e5fd3043a7f3 100644 --- a/x/auth/middleware/testutil_test.go +++ b/x/auth/middleware/testutil_test.go @@ -43,7 +43,7 @@ type MWTestSuite struct { // returns context and app with params set on account keeper func createTestApp(t *testing.T, isCheckTx bool) (*simapp.SimApp, sdk.Context) { app := simapp.Setup(t, isCheckTx) - ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}).WithBlockGasMeter(sdk.NewInfiniteGasMeter()) + ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{Height: app.LastBlockHeight() + 1}).WithBlockGasMeter(sdk.NewInfiniteGasMeter()) app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams()) return app, ctx @@ -53,7 +53,6 @@ func createTestApp(t *testing.T, isCheckTx bool) (*simapp.SimApp, sdk.Context) { func (s *MWTestSuite) SetupTest(isCheckTx bool) sdk.Context { var ctx sdk.Context s.app, ctx = createTestApp(s.T(), isCheckTx) - ctx = ctx.WithBlockHeight(1) // Set up TxConfig. encodingConfig := simapp.MakeTestEncodingConfig() diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go index d23f15e3ea2e..3fa30d6753b4 100644 --- a/x/auth/middleware/tips_test.go +++ b/x/auth/middleware/tips_test.go @@ -41,10 +41,11 @@ func (s *MWTestSuite) setupMetaTxAccts(ctx sdk.Context) (sdk.Context, []testAcco s.app.GovKeeper.ActivateVotingPeriod(ctx, prop) // Move to next block to commit previous data to state. - s.app.EndBlock(abci.RequestEndBlock{Height: 1}) + s.app.EndBlock(abci.RequestEndBlock{Height: ctx.BlockHeight()}) s.app.Commit() - s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 2}}) - ctx = ctx.WithBlockHeight(2) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: ctx.BlockHeight()}}) return ctx, accts } @@ -208,9 +209,11 @@ func (s *MWTestSuite) mkTipperTxBuilder( // Actually sign the data. signerData := authsigning.SignerData{ + Address: sdk.AccAddress(tipperPriv.PubKey().Address()).String(), ChainID: chainID, AccountNumber: accNum, Sequence: accSeq, + SignerIndex: 0, } sigV2, err := clienttx.SignWithPrivKey( signMode, signerData, @@ -253,9 +256,11 @@ func mkFeePayerTxBuilder( // Actually sign the data. signerData := authsigning.SignerData{ + Address: sdk.AccAddress(feePayerPriv.PubKey().Address()).String(), ChainID: chainID, AccountNumber: accNum, Sequence: accSeq, + SignerIndex: 1, } feePayerSigV2, err = clienttx.SignWithPrivKey( signMode, signerData, From a606970a2ac13d42f98d5a4f6223f546cfb79f3a Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 19 Oct 2021 15:17:40 +0200 Subject: [PATCH 31/40] Add more gas --- x/auth/middleware/tips_test.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go index 3fa30d6753b4..0e2dd5d2342c 100644 --- a/x/auth/middleware/tips_test.go +++ b/x/auth/middleware/tips_test.go @@ -108,22 +108,22 @@ func (s *MWTestSuite) TestTips() { { "tipper should be equal to msg signer", randomAddr, // arbitrary msg signer, not equal to tipper - sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 100000, + sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 200000, true, "pubKey does not match signer address", }, { "wrong tip denom", nil, - sdk.NewCoins(sdk.NewCoin("foobar", sdk.NewInt(1000))), initialAtoms, 100000, + sdk.NewCoins(sdk.NewCoin("foobar", sdk.NewInt(1000))), initialAtoms, 200000, true, "0foobar is smaller than 1000foobar: insufficient funds", }, { "insufficient tip from tipper", nil, - sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 100000, + sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 200000, true, "1000regen is smaller than 5000regen: insufficient funds", }, { "insufficient fees from feePayer", nil, - initialRegens, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(5000))), 100000, + initialRegens, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(5000))), 200000, true, "1000atom is smaller than 5000atom: insufficient funds: insufficient funds", }, { @@ -133,7 +133,7 @@ func (s *MWTestSuite) TestTips() { }, { "happy case", nil, - initialRegens, initialAtoms, 100000, + initialRegens, initialAtoms, 200000, false, "", }, } @@ -165,10 +165,11 @@ func (s *MWTestSuite) TestTips() { s.Require().NotNil(res) // Move to next block to commit previous data to state. - s.app.EndBlock(abci.RequestEndBlock{Height: 2}) + s.app.EndBlock(abci.RequestEndBlock{Height: ctx.BlockHeight()}) s.app.Commit() - s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 3}}) - ctx = ctx.WithBlockHeight(3) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + s.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: ctx.BlockHeight()}}) // Make sure tip is correctly transferred to feepayer, and fee is paid. expTipperRegens := initialRegens.Sub(tc.tip) From 7602d4d61384c263b6f138a27fbd04f6821cbca7 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Fri, 22 Oct 2021 14:57:33 +0200 Subject: [PATCH 32/40] Address reviews --- CHANGELOG.md | 1 + x/auth/migrations/legacytx/stdtx_test.go | 5 ----- x/auth/tx/legacy_amino_json_test.go | 7 +------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c98334aa468..fa9f09e139e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Move Baseapp panic recovery into a middleware. * Rename simulation helper methods `baseapp.{Check,Deliver}` to `baseapp.Sim{Check,Deliver}**`. * (x/gov) [\#10373](https://github.com/cosmos/cosmos-sdk/pull/10373) Removed gov `keeper.{MustMarshal, MustUnmarshal}`. +* [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) StdSignBytes takes a new argument of type `*tx.Tip` for signing over tips using LEGACY_AMINO_JSON. ### Client Breaking Changes diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 6bb7c353bf91..650f6f4b155c 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -125,11 +125,6 @@ func TestStdSignBytes(t *testing.T) { args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String(), Granter: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","granter":"%s","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr, addr), }, - { - "no tip (omitempty)", - args{"1234", 3, 6, 0, StdFee{Amount: defaultFee.Amount, Gas: defaultFee.Gas, Payer: addr.String()}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", nil}, - fmt.Sprintf(`{"account_number":"3","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"100000","payer":"%s"},"memo":"memo","msgs":[["%s"]],"sequence":"6"}`, addr, addr), - }, { "no fee, with tip", args{"1234", 3, 6, 0, StdFee{}, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo", defaultTip}, diff --git a/x/auth/tx/legacy_amino_json_test.go b/x/auth/tx/legacy_amino_json_test.go index 95d641619cfd..9734e7704eea 100644 --- a/x/auth/tx/legacy_amino_json_test.go +++ b/x/auth/tx/legacy_amino_json_test.go @@ -68,7 +68,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas, Granter: addr2.String()}, []sdk.Msg{msg}, memo, nil), }, { - "explicit fee payer and feegranter", addr1.String(), + "explicit fee payer and fee granter", addr1.String(), func(w *wrapper) { w.SetFeePayer(addr2) w.SetFeeGranter(addr2) @@ -80,11 +80,6 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) { func(w *wrapper) { w.SetTip(tip) }, legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{}, []sdk.Msg{msg}, memo, tip), }, - { - "signer which is not tipper", addr2.String(), - func(w *wrapper) { w.SetTip(tip) }, - legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{Amount: coins, Gas: gas}, []sdk.Msg{msg}, memo, tip), - }, } handler := signModeLegacyAminoJSONHandler{} From a424a34fa87d4bb5249a623cffb6ebe2d8099667 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 26 Oct 2021 12:55:29 +0200 Subject: [PATCH 33/40] Remove sign mode middleware --- x/auth/middleware/middleware.go | 1 - x/auth/middleware/tips.go | 161 +------------------------------- x/auth/middleware/tips_test.go | 44 --------- x/auth/tx/direct_aux.go | 16 +++- x/auth/tx/direct_aux_test.go | 35 +++++-- 5 files changed, 46 insertions(+), 211 deletions(-) diff --git a/x/auth/middleware/middleware.go b/x/auth/middleware/middleware.go index f75f5641a42a..c34ac1832dc8 100644 --- a/x/auth/middleware/middleware.go +++ b/x/auth/middleware/middleware.go @@ -92,7 +92,6 @@ func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) { SetPubKeyMiddleware(options.AccountKeeper), ValidateSigCountMiddleware(options.AccountKeeper), SigGasConsumeMiddleware(options.AccountKeeper, sigGasConsumer), - SignModeTxMiddleware, SigVerificationMiddleware(options.AccountKeeper, options.SignModeHandler), NewTipsTxMiddleware(options.BankKeeper), IncrementSequenceMiddleware(options.AccountKeeper), diff --git a/x/auth/middleware/tips.go b/x/auth/middleware/tips.go index 580c42b08380..5716454b3484 100644 --- a/x/auth/middleware/tips.go +++ b/x/auth/middleware/tips.go @@ -6,10 +6,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -18,8 +15,8 @@ type tipsTxHandler struct { bankKeeper types.BankKeeper } -// NewTipsTxMiddleware returns a new middleware for handling meta-transactions -// with tips. +// NewTipsTxMiddleware returns a new middleware for handling transactions with +// tips. func NewTipsTxMiddleware(bankKeeper types.BankKeeper) tx.Middleware { return func(txh tx.Handler) tx.Handler { return tipsTxHandler{txh, bankKeeper} @@ -95,157 +92,3 @@ func (txh tipsTxHandler) transferTip(ctx context.Context, tipTx tx.TipTx) error return txh.bankKeeper.SendCoins(sdkCtx, tipper, tipTx.FeePayer(), tipTx.GetTip().Amount) } - -type signModeTxHandler struct { - next tx.Handler -} - -// SignModeTxMiddleware returns a new middleware that checks that -// all signatures in the tx have correct sign modes. -// Namely: -// - fee payer should sign over fees, -// - tipper should signer over tips. -func SignModeTxMiddleware(txh tx.Handler) tx.Handler { - return signModeTxHandler{txh} -} - -var _ tx.Handler = signModeTxHandler{} - -// CheckTx implements tx.Handler.CheckTx. -func (txh signModeTxHandler) CheckTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestCheckTx) (abci.ResponseCheckTx, error) { - if err := checkSignMode(sdkTx); err != nil { - return abci.ResponseCheckTx{}, err - } - - return txh.next.CheckTx(ctx, sdkTx, req) -} - -// DeliverTx implements tx.Handler.DeliverTx. -func (txh signModeTxHandler) DeliverTx(ctx context.Context, sdkTx sdk.Tx, req abci.RequestDeliverTx) (abci.ResponseDeliverTx, error) { - if err := checkSignMode(sdkTx); err != nil { - return abci.ResponseDeliverTx{}, err - } - - return txh.next.DeliverTx(ctx, sdkTx, req) -} - -// SimulateTx implements tx.Handler.SimulateTx method. -func (txh signModeTxHandler) SimulateTx(ctx context.Context, sdkTx sdk.Tx, req tx.RequestSimulateTx) (tx.ResponseSimulateTx, error) { - if err := checkSignMode(sdkTx); err != nil { - return tx.ResponseSimulateTx{}, err - } - - return txh.next.SimulateTx(ctx, sdkTx, req) -} - -// checkSignMode checks that all signatures in the tx have correct sign modes. -// Namely: -// - fee payer should sign over fees, -// - tipper should signer over tips. -func checkSignMode(sdkTx sdk.Tx) error { - tipTx, ok := sdkTx.(tx.TipTx) - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrTxDecode, "tx must be a TipTx, got %T", sdkTx) - } - feePayer := tipTx.FeePayer() - var tipper string - if tip := tipTx.GetTip(); tip != nil { - tipper = tipTx.GetTip().Tipper - } - - sigTx, ok := sdkTx.(authsigning.SigVerifiableTx) - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrTxDecode, "tx must be a SigVerifiableTx, got %T", sdkTx) - } - sigsV2, err := sigTx.GetSignaturesV2() - if err != nil { - return err - } - - for _, sig := range sigsV2 { - addr := sdk.AccAddress(sig.PubKey.Address()) - - // Make sure the feePayer signs over the Fee. - if addr.Equals(feePayer) { - if err := checkFeeSigner(addr, sig.Data); err != nil { - return err - } - } - - // Make sure the tipper signs over the Tip. - if addr.String() == tipper { - if err := checkTipSigner(addr, sig.Data); err != nil { - return err - } - } - } - - return nil -} - -// checkFeeSigner checks whether a signature has signed over Fees. -func checkFeeSigner(addr sdk.AccAddress, sigData signing.SignatureData) error { - if err := checkCorrectSignModes(addr, sigData, []signing.SignMode{ - signing.SignMode_SIGN_MODE_DIRECT, - signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - }, "fee payer"); err != nil { - return err - } - - return nil -} - -// checkTipSigner checks whether a signature has signed over Tips. -func checkTipSigner(addr sdk.AccAddress, sigData signing.SignatureData) error { - if err := checkCorrectSignModes(addr, sigData, []signing.SignMode{ - signing.SignMode_SIGN_MODE_DIRECT, - signing.SignMode_SIGN_MODE_DIRECT_AUX, - signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - }, "tipper"); err != nil { - return err - } - - return nil -} - -// checkCorrectSignModes checks that all signatures are one of the allowed -// sign modes defined in `allowedSignModes`. -// For multi-signatures, check recursively. -func checkCorrectSignModes( - addr sdk.AccAddress, - sigData signing.SignatureData, - allowedSignModes []signing.SignMode, - errString string, -) error { - switch sigData := sigData.(type) { - case *signing.SingleSignatureData: - { - if !arrayIncludes(allowedSignModes, sigData.SignMode) { - return sdkerrors.ErrUnauthorized.Wrapf("invalid sign mode for %s %s, got %s", errString, addr, sigData.SignMode) - } - } - case *signing.MultiSignatureData: - { - for _, s := range sigData.Signatures { - err := checkCorrectSignModes(addr, s, allowedSignModes, errString) - if err != nil { - return err - } - } - } - default: - return sdkerrors.ErrInvalidType.Wrapf("got unexpected SignatureData %T", sigData) - } - - return nil -} - -func arrayIncludes(sms []signing.SignMode, sm signing.SignMode) bool { - for _, x := range sms { - if x == sm { - return true - } - } - - return false -} diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go index 0e2dd5d2342c..1fd86e64291c 100644 --- a/x/auth/middleware/tips_test.go +++ b/x/auth/middleware/tips_test.go @@ -1,7 +1,6 @@ package middleware_test import ( - "fmt" "time" abci "github.com/tendermint/tendermint/abci/types" @@ -14,7 +13,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/middleware" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" @@ -50,48 +48,6 @@ func (s *MWTestSuite) setupMetaTxAccts(ctx sdk.Context) (sdk.Context, []testAcco return ctx, accts } -func (s *MWTestSuite) TestSignModes() { - ctx := s.SetupTest(false) // reset - ctx, accts := s.setupMetaTxAccts(ctx) - tipper, feePayer := accts[0], accts[1] - msg := govtypes.NewMsgVote(tipper.acc.GetAddress(), 1, govtypes.OptionYes) - - txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.SignModeTxMiddleware) - - testcases := []struct { - tipperSignMode signing.SignMode - feePayerSignMode signing.SignMode - expErr bool - }{ - {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_DIRECT, false}, - {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, - {signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, - {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_DIRECT, false}, - {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, - {signing.SignMode_SIGN_MODE_DIRECT_AUX, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, - {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_DIRECT, false}, - {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_DIRECT_AUX, true}, - {signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, false}, - } - - for _, tc := range testcases { - tc := tc - s.Run(fmt.Sprintf("tipper=%s, feepayer=%s", tc.tipperSignMode, tc.feePayerSignMode), func() { - tipperTxBuilder := s.mkTipperTxBuilder(tipper.priv, msg, initialRegens, tc.tipperSignMode, tipper.accNum, 0, ctx.ChainID()) - feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, feePayer.priv, tc.feePayerSignMode, tx.Fee{Amount: initialAtoms, GasLimit: 200000}, tipperTxBuilder.GetTx(), feePayer.accNum, 0, ctx.ChainID()) - s.Require().NoError(err) - - _, err = txHandler.DeliverTx(sdk.WrapSDKContext(ctx), feePayerTxBuilder.GetTx(), abci.RequestDeliverTx{}) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), "invalid sign mode for") - } else { - s.Require().NoError(err) - } - }) - } -} - func (s *MWTestSuite) TestTips() { var msg sdk.Msg _, _, randomAddr := testdata.KeyTestPubAddr() diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 71a3fd5c0426..b379aacf97a9 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -44,11 +44,25 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, sdkerrors.ErrInvalidRequest.Wrapf("got empty pubkey for signer #%d in %s handler", data.SignerIndex, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } + // Fee payer cannot use SIGN_MODE_DIRECT_AUX, because SIGN_MODE_DIRECT_AUX + // does not sign over fees, which would create malleability issues. + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return nil, sdkerrors.ErrInvalidType.Wrapf("expected %T, got %T", sdk.FeeTx(nil), tx) + } + addr := data.Address + if addr == "" { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) + } + if feeTx.FeePayer().String() == data.Address { + return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feeTx.FeePayer(), signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) + } + signDocDirectAux := types.SignDocDirectAux{ BodyBytes: protoTx.getBodyBytes(), ChainId: data.ChainID, AccountNumber: data.AccountNumber, - Sequence: data.Sequence, + Sequence: signerInfo.Sequence, Tip: protoTx.tx.AuthInfo.Tip, PublicKey: signerInfo.PublicKey, } diff --git a/x/auth/tx/direct_aux_test.go b/x/auth/tx/direct_aux_test.go index df7460c5ba78..6bd67024a259 100644 --- a/x/auth/tx/direct_aux_test.go +++ b/x/auth/tx/direct_aux_test.go @@ -17,6 +17,7 @@ import ( func TestDirectAuxHandler(t *testing.T) { privKey, pubkey, addr := testdata.KeyTestPubAddr() + _, feePayerPubKey, feePayerAddr := testdata.KeyTestPubAddr() interfaceRegistry := codectypes.NewInterfaceRegistry() interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) marshaler := codec.NewProtoCodec(interfaceRegistry) @@ -24,9 +25,10 @@ func TestDirectAuxHandler(t *testing.T) { txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT_AUX}) txBuilder := txConfig.NewTxBuilder() + chainID := "test-chain" memo := "sometestmemo" msgs := []sdk.Msg{testdata.NewTestMsg(addr)} - accSeq := uint64(2) // Arbitrary account sequence + accNum, accSeq := uint64(1), uint64(2) // Arbitrary account number/sequence any, err := codectypes.NewAnyWithValue(pubkey) require.NoError(t, err) @@ -40,26 +42,46 @@ func TestDirectAuxHandler(t *testing.T) { Data: sigData, Sequence: accSeq, } + feePayerSig := signingtypes.SignatureV2{ + PubKey: feePayerPubKey, + Data: sigData, + Sequence: accSeq, + } fee := txtypes.Fee{Amount: sdk.NewCoins(sdk.NewInt64Coin("atom", 150)), GasLimit: 20000} + tip := &txtypes.Tip{Amount: sdk.NewCoins(sdk.NewInt64Coin("tip-token", 10))} err = txBuilder.SetMsgs(msgs...) require.NoError(t, err) txBuilder.SetMemo(memo) txBuilder.SetFeeAmount(fee.Amount) + txBuilder.SetFeePayer(feePayerAddr) txBuilder.SetGasLimit(fee.GasLimit) + txBuilder.SetTip(tip) - err = txBuilder.SetSignatures(sig) + err = txBuilder.SetSignatures(sig, feePayerSig) require.NoError(t, err) signingData := signing.SignerData{ Address: addr.String(), - ChainID: "test-chain", - AccountNumber: 1, + ChainID: chainID, + AccountNumber: accNum, SignerIndex: 0, } + feePayerSigningData := signing.SignerData{ + Address: feePayerAddr.String(), + ChainID: chainID, + AccountNumber: accNum, + SignerIndex: 1, + } modeHandler := signModeDirectAuxHandler{} + + t.Log("verify fee payer cannot use SIGN_MODE_DIRECT_AUX") + _, err = modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, feePayerSigningData, txBuilder.GetTx()) + require.EqualError(t, err, fmt.Sprintf("fee payer %s cannot sign with %s: unauthorized", feePayerAddr.String(), signingtypes.SignMode_SIGN_MODE_DIRECT_AUX)) + + t.Log("verify GetSignBytes with generating sign bytes by marshaling signDocDirectAux") signBytes, err := modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT_AUX, signingData, txBuilder.GetTx()) require.NoError(t, err) require.NotNil(t, signBytes) @@ -79,12 +101,13 @@ func TestDirectAuxHandler(t *testing.T) { } bodyBytes := marshaler.MustMarshal(txBody) - t.Log("verify GetSignBytes with generating sign bytes by marshaling signDocDirectAux") signDocDirectAux := txtypes.SignDocDirectAux{ - AccountNumber: 1, + AccountNumber: accNum, BodyBytes: bodyBytes, ChainId: "test-chain", PublicKey: any, + Sequence: accSeq, + Tip: tip, } expectedSignBytes, err := signDocDirectAux.Marshal() From c5bfc3b8ccc41c820717b6da5073e41b732141ba Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 26 Oct 2021 14:30:49 +0200 Subject: [PATCH 34/40] Fix direct_aux sign mode handler --- CHANGELOG.md | 2 +- types/tx/types.go | 8 ++++---- x/auth/tx/builder.go | 12 +++++------- x/auth/tx/direct_aux.go | 36 ++++++++++++++++++++++++++++-------- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e25e2ccc525..6e356592145a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,7 +52,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10326](https://github.com/cosmos/cosmos-sdk/pull/10326) `x/authz` add query all grants by granter query. * [\#10024](https://github.com/cosmos/cosmos-sdk/pull/10024) `store/cachekv` performance improvement by reduced growth factor for iterator ranging by using binary searches to find dirty items when unsorted key count >= 1024 * [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. -* [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) Add `SignModeTxMiddleware` for checking sign modes and `TipsTxMiddleware` for transferring tips. +* [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) Add `TipsTxMiddleware` for transferring tips. ### API Breaking Changes diff --git a/types/tx/types.go b/types/tx/types.go index 43982731f1c4..a25aba880391 100644 --- a/types/tx/types.go +++ b/types/tx/types.go @@ -112,14 +112,14 @@ func (t *Tx) GetSigners() []sdk.AccAddress { } // ensure any specified fee payer is included in the required signers (at the end) - feePayer := t.AuthInfo.Fee.Payer - if feePayer != "" && !seen[feePayer] { - payerAddr, err := sdk.AccAddressFromBech32(feePayer) + fee := t.AuthInfo.Fee + if fee != nil && fee.Payer != "" && !seen[fee.Payer] { + payerAddr, err := sdk.AccAddressFromBech32(fee.Payer) if err != nil { panic(err) } signers = append(signers, payerAddr) - seen[feePayer] = true + seen[fee.Payer] = true } return signers diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index d3b83d5018bb..fcc3c4caee87 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -49,10 +49,8 @@ type ExtensionOptionsTxBuilder interface { func newBuilder() *wrapper { return &wrapper{ tx: &tx.Tx{ - Body: &tx.TxBody{}, - AuthInfo: &tx.AuthInfo{ - Fee: &tx.Fee{}, - }, + Body: &tx.TxBody{}, + AuthInfo: &tx.AuthInfo{}, }, } } @@ -133,9 +131,9 @@ func (w *wrapper) GetFee() sdk.Coins { } func (w *wrapper) FeePayer() sdk.AccAddress { - feePayer := w.tx.AuthInfo.Fee.Payer - if feePayer != "" { - payerAddr, err := sdk.AccAddressFromBech32(feePayer) + fee := w.tx.AuthInfo.Fee + if fee != nil && fee.Payer != "" { + payerAddr, err := sdk.AccAddressFromBech32(fee.Payer) if err != nil { panic(err) } diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index b379aacf97a9..98d10b745062 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -44,18 +44,38 @@ func (signModeDirectAuxHandler) GetSignBytes( return nil, sdkerrors.ErrInvalidRequest.Wrapf("got empty pubkey for signer #%d in %s handler", data.SignerIndex, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } - // Fee payer cannot use SIGN_MODE_DIRECT_AUX, because SIGN_MODE_DIRECT_AUX - // does not sign over fees, which would create malleability issues. - feeTx, ok := tx.(sdk.FeeTx) - if !ok { - return nil, sdkerrors.ErrInvalidType.Wrapf("expected %T, got %T", sdk.FeeTx(nil), tx) - } addr := data.Address if addr == "" { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "got empty address in %s handler", signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } - if feeTx.FeePayer().String() == data.Address { - return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feeTx.FeePayer(), signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) + + feePayer := protoTx.FeePayer().String() + + // Fee payer cannot use SIGN_MODE_DIRECT_AUX, because SIGN_MODE_DIRECT_AUX + // does not sign over fees, which would create malleability issues. + if feePayer == data.Address { + tip := protoTx.tx.GetAuthInfo().GetTip() + var tipper string + if tip != nil { + tipper = tip.Tipper + } + + // In general, the transactions with tips require that the fee payer and + // tipper are two different persons. + // + // However, recall that `protoTx.FeePayer()` is defined as + // `tx.AuthInfo.Fee.Payer` if not nil, or defaults to `tx.GetSigners[0]`. + // When fee payer is `tx.GetSigners[0]` (i.e. the tx.AuthInfo.Fee.Payer + // field is not set), then the tipper and the fee payer + // are the same person. Concretely, this happens when the tipper signs + // their tx before relaying it to the fee payer. + if tipper == feePayer { + if protoTx.tx.GetAuthInfo().GetFee() != nil { + return nil, sdkerrors.ErrUnauthorized.Wrapf("tipper %s cannot be fee payer", tipper) + } + } else { + return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feePayer, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) + } } signDocDirectAux := types.SignDocDirectAux{ From 64123edb5970b502d6498a9da31121e6c102f496 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 26 Oct 2021 14:54:29 +0200 Subject: [PATCH 35/40] Fix test --- x/auth/testutil/suite.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/auth/testutil/suite.go b/x/auth/testutil/suite.go index b9bcc8a9c609..e1080f067ab4 100644 --- a/x/auth/testutil/suite.go +++ b/x/auth/testutil/suite.go @@ -89,6 +89,7 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { msigAddr := sdk.AccAddress(multisigPk.Address()) msg2 := testdata.NewTestMsg(msigAddr) err := txBuilder.SetMsgs(msg, msg2) + txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) s.Require().NoError(err) // check that validation fails From d6b597040d2b8fd3063606c58fe63b90c8796869 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Nov 2021 11:03:10 +0100 Subject: [PATCH 36/40] Fix build --- types/tx/types.go | 8 +++---- x/auth/migrations/legacytx/stdtx_builder.go | 3 --- x/auth/tx/builder.go | 12 ++++++----- x/auth/tx/direct_aux.go | 23 +-------------------- 4 files changed, 12 insertions(+), 34 deletions(-) diff --git a/types/tx/types.go b/types/tx/types.go index a25aba880391..43982731f1c4 100644 --- a/types/tx/types.go +++ b/types/tx/types.go @@ -112,14 +112,14 @@ func (t *Tx) GetSigners() []sdk.AccAddress { } // ensure any specified fee payer is included in the required signers (at the end) - fee := t.AuthInfo.Fee - if fee != nil && fee.Payer != "" && !seen[fee.Payer] { - payerAddr, err := sdk.AccAddressFromBech32(fee.Payer) + feePayer := t.AuthInfo.Fee.Payer + if feePayer != "" && !seen[feePayer] { + payerAddr, err := sdk.AccAddressFromBech32(feePayer) if err != nil { panic(err) } signers = append(signers, payerAddr) - seen[fee.Payer] = true + seen[feePayer] = true } return signers diff --git a/x/auth/migrations/legacytx/stdtx_builder.go b/x/auth/migrations/legacytx/stdtx_builder.go index 81fbe802bf0c..9586f3c8b3f2 100644 --- a/x/auth/migrations/legacytx/stdtx_builder.go +++ b/x/auth/migrations/legacytx/stdtx_builder.go @@ -77,9 +77,6 @@ func (s *StdTxBuilder) SetFeePayer(_ sdk.AccAddress) {} // SetFeeGranter does nothing for stdtx func (s *StdTxBuilder) SetFeeGranter(_ sdk.AccAddress) {} -// SetFeePayer does nothing for stdtx -func (s *StdTxBuilder) SetFeePayer(_ sdk.AccAddress) {} - // AddAuxSignerData returns an error for StdTxBuilder. func (s *StdTxBuilder) AddAuxSignerData(_ tx.AuxSignerData) error { return sdkerrors.ErrLogic.Wrap("cannot use AuxSignerData with StdTxBuilder") diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index 33a1f6ea07a6..91e3546c74d7 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -53,8 +53,10 @@ func newBuilder(cdc codec.Codec) *wrapper { return &wrapper{ cdc: cdc, tx: &tx.Tx{ - Body: &tx.TxBody{}, - AuthInfo: &tx.AuthInfo{}, + Body: &tx.TxBody{}, + AuthInfo: &tx.AuthInfo{ + Fee: &tx.Fee{}, + }, }, } } @@ -135,9 +137,9 @@ func (w *wrapper) GetFee() sdk.Coins { } func (w *wrapper) FeePayer() sdk.AccAddress { - fee := w.tx.AuthInfo.Fee - if fee != nil && fee.Payer != "" { - payerAddr, err := sdk.AccAddressFromBech32(fee.Payer) + feePayer := w.tx.AuthInfo.Fee.Payer + if feePayer != "" { + payerAddr, err := sdk.AccAddressFromBech32(feePayer) if err != nil { panic(err) } diff --git a/x/auth/tx/direct_aux.go b/x/auth/tx/direct_aux.go index 98d10b745062..63aba24918f8 100644 --- a/x/auth/tx/direct_aux.go +++ b/x/auth/tx/direct_aux.go @@ -54,28 +54,7 @@ func (signModeDirectAuxHandler) GetSignBytes( // Fee payer cannot use SIGN_MODE_DIRECT_AUX, because SIGN_MODE_DIRECT_AUX // does not sign over fees, which would create malleability issues. if feePayer == data.Address { - tip := protoTx.tx.GetAuthInfo().GetTip() - var tipper string - if tip != nil { - tipper = tip.Tipper - } - - // In general, the transactions with tips require that the fee payer and - // tipper are two different persons. - // - // However, recall that `protoTx.FeePayer()` is defined as - // `tx.AuthInfo.Fee.Payer` if not nil, or defaults to `tx.GetSigners[0]`. - // When fee payer is `tx.GetSigners[0]` (i.e. the tx.AuthInfo.Fee.Payer - // field is not set), then the tipper and the fee payer - // are the same person. Concretely, this happens when the tipper signs - // their tx before relaying it to the fee payer. - if tipper == feePayer { - if protoTx.tx.GetAuthInfo().GetFee() != nil { - return nil, sdkerrors.ErrUnauthorized.Wrapf("tipper %s cannot be fee payer", tipper) - } - } else { - return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feePayer, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) - } + return nil, sdkerrors.ErrUnauthorized.Wrapf("fee payer %s cannot sign with %s", feePayer, signingtypes.SignMode_SIGN_MODE_DIRECT_AUX) } signDocDirectAux := types.SignDocDirectAux{ From e933fc42e062f63ec1923cbacfa5460455c9cef7 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Nov 2021 11:41:42 +0100 Subject: [PATCH 37/40] Fix tests using AuxTxBuilder --- types/tx/aux.go | 17 +++++++ types/tx/aux_test.go | 7 +++ x/auth/middleware/tips_test.go | 91 +++++++++++++--------------------- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/types/tx/aux.go b/types/tx/aux.go index 2c9a71262252..73189ff840c5 100644 --- a/types/tx/aux.go +++ b/types/tx/aux.go @@ -48,6 +48,23 @@ func (a *AuxSignerData) ValidateBasic() error { return a.GetSignDoc().ValidateBasic() } +// GetSignaturesV2 gets the SignatureV2 of the aux signer. +func (a *AuxSignerData) GetSignatureV2() (signing.SignatureV2, error) { + pk, ok := a.SignDoc.PublicKey.GetCachedValue().(cryptotypes.PubKey) + if !ok { + return signing.SignatureV2{}, sdkerrors.ErrInvalidType.Wrapf("expected %T, got %T", (cryptotypes.PubKey)(nil), pk) + } + + return signing.SignatureV2{ + PubKey: pk, + Data: &signing.SingleSignatureData{ + SignMode: a.Mode, + Signature: a.Sig, + }, + Sequence: a.SignDoc.Sequence, + }, nil +} + // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method func (a *AuxSignerData) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { return a.GetSignDoc().UnpackInterfaces(unpacker) diff --git a/types/tx/aux_test.go b/types/tx/aux_test.go index 02b39f0f356e..7120126c0215 100644 --- a/types/tx/aux_test.go +++ b/types/tx/aux_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -77,6 +78,12 @@ func TestAuxSignerData(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) + sigV2, err := tc.sd.GetSignatureV2() + require.NoError(t, err) + require.Equal(t, tc.sd.Mode, sigV2.Data.(*signing.SingleSignatureData).SignMode) + require.Equal(t, tc.sd.Sig, sigV2.Data.(*signing.SingleSignatureData).Signature) + require.Equal(t, tc.sd.SignDoc.Sequence, sigV2.Sequence) + require.True(t, tc.sd.SignDoc.PublicKey.GetCachedValue().(cryptotypes.PubKey).Equals(sigV2.PubKey)) } }) } diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go index 1fd86e64291c..4d6a06614b38 100644 --- a/x/auth/middleware/tips_test.go +++ b/x/auth/middleware/tips_test.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" clienttx "github.com/cosmos/cosmos-sdk/client/tx" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -50,11 +49,9 @@ func (s *MWTestSuite) setupMetaTxAccts(ctx sdk.Context) (sdk.Context, []testAcco func (s *MWTestSuite) TestTips() { var msg sdk.Msg - _, _, randomAddr := testdata.KeyTestPubAddr() testcases := []struct { name string - msgSigner sdk.AccAddress tip sdk.Coins fee sdk.Coins gasLimit uint64 @@ -62,33 +59,27 @@ func (s *MWTestSuite) TestTips() { expErrStr string }{ { - "tipper should be equal to msg signer", - randomAddr, // arbitrary msg signer, not equal to tipper - sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 200000, - true, "pubKey does not match signer address", - }, - { - "wrong tip denom", nil, + "wrong tip denom", sdk.NewCoins(sdk.NewCoin("foobar", sdk.NewInt(1000))), initialAtoms, 200000, true, "0foobar is smaller than 1000foobar: insufficient funds", }, { - "insufficient tip from tipper", nil, + "insufficient tip from tipper", sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(5000))), initialAtoms, 200000, true, "1000regen is smaller than 5000regen: insufficient funds", }, { - "insufficient fees from feePayer", nil, + "insufficient fees from feePayer", initialRegens, sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(5000))), 200000, true, "1000atom is smaller than 5000atom: insufficient funds: insufficient funds", }, { - "insufficient gas", nil, + "insufficient gas", initialRegens, initialAtoms, 100, true, "out of gas in location: ReadFlat; gasWanted: 100, gasUsed: 1000: out of gas", }, { - "happy case", nil, + "happy case", initialRegens, initialAtoms, 200000, false, "", }, @@ -101,14 +92,10 @@ func (s *MWTestSuite) TestTips() { ctx, accts := s.setupMetaTxAccts(ctx) tipper, feePayer := accts[0], accts[1] - voter := tc.msgSigner - if voter == nil { - voter = tipper.acc.GetAddress() // Choose tipper as MsgSigner, unless overwritten by testcase. - } - msg = govtypes.NewMsgVote(voter, 1, govtypes.OptionYes) + msg = govtypes.NewMsgVote(tipper.acc.GetAddress(), 1, govtypes.OptionYes) - tipperTxBuilder := s.mkTipperTxBuilder(tipper.priv, msg, tc.tip, signing.SignMode_SIGN_MODE_DIRECT_AUX, tipper.accNum, 0, ctx.ChainID()) - feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, feePayer.priv, signing.SignMode_SIGN_MODE_DIRECT, tx.Fee{Amount: tc.fee, GasLimit: tc.gasLimit}, tipperTxBuilder.GetTx(), feePayer.accNum, 0, ctx.ChainID()) + auxSignerData := s.mkTipperAuxSignerData(tipper.priv, msg, tc.tip, signing.SignMode_SIGN_MODE_DIRECT_AUX, tipper.accNum, 0, ctx.ChainID()) + feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, auxSignerData, feePayer.priv, signing.SignMode_SIGN_MODE_DIRECT, tx.Fee{Amount: tc.fee, GasLimit: tc.gasLimit}, feePayer.accNum, 0, ctx.ChainID()) s.Require().NoError(err) _, res, err := s.app.SimDeliver(s.clientCtx.TxConfig.TxEncoder(), feePayerTxBuilder.GetTx()) @@ -143,62 +130,54 @@ func (s *MWTestSuite) TestTips() { } } -func (s *MWTestSuite) mkTipperTxBuilder( +func (s *MWTestSuite) mkTipperAuxSignerData( tipperPriv cryptotypes.PrivKey, msg sdk.Msg, tip sdk.Coins, signMode signing.SignMode, accNum, accSeq uint64, chainID string, -) client.TxBuilder { - txBuilder := s.clientCtx.TxConfig.NewTxBuilder() - txBuilder.SetTip(&tx.Tip{ - Amount: tip, - Tipper: sdk.AccAddress(tipperPriv.PubKey().Address()).String(), - }) - err := txBuilder.SetMsgs(msg) +) tx.AuxSignerData { + tipperAddr := sdk.AccAddress(tipperPriv.PubKey().Address()).String() + b := clienttx.NewAuxTxBuilder() + b.SetAddress(tipperAddr) + b.SetAccountNumber(accNum) + b.SetSequence(accSeq) + err := b.SetMsgs(msg) s.Require().NoError(err) - - // Call SetSignatures with empty sig to populate AuthInfo. - err = txBuilder.SetSignatures(signing.SignatureV2{ - PubKey: tipperPriv.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: signMode, - Signature: nil, - }}) + b.SetTip(&tx.Tip{Amount: tip, Tipper: tipperAddr}) + err = b.SetSignMode(signMode) + s.Require().NoError(err) + b.SetSequence(accSeq) + err = b.SetPubKey(tipperPriv.PubKey()) s.Require().NoError(err) + b.SetChainID(chainID) - // Actually sign the data. - signerData := authsigning.SignerData{ - Address: sdk.AccAddress(tipperPriv.PubKey().Address()).String(), - ChainID: chainID, - AccountNumber: accNum, - Sequence: accSeq, - SignerIndex: 0, - } - sigV2, err := clienttx.SignWithPrivKey( - signMode, signerData, - txBuilder, tipperPriv, s.clientCtx.TxConfig, accSeq) + signBz, err := b.GetSignBytes() s.Require().NoError(err) + sig, err := tipperPriv.Sign(signBz) + s.Require().NoError(err) + b.SetSignature(sig) - txBuilder.SetSignatures(sigV2) + auxSignerData, err := b.GetAuxSignerData() + s.Require().NoError(err) - return txBuilder + return auxSignerData } func mkFeePayerTxBuilder( clientCtx client.Context, + auxSignerData tx.AuxSignerData, feePayerPriv cryptotypes.PrivKey, signMode signing.SignMode, - fee tx.Fee, tipTx tx.TipTx, accNum, accSeq uint64, chainID string, + fee tx.Fee, accNum, accSeq uint64, chainID string, ) (client.TxBuilder, error) { txBuilder := clientCtx.TxConfig.NewTxBuilder() - err := txBuilder.SetMsgs(tipTx.GetMsgs()...) + err := txBuilder.AddAuxSignerData(auxSignerData) if err != nil { return nil, err } txBuilder.SetFeePayer(sdk.AccAddress(feePayerPriv.PubKey().Address())) txBuilder.SetFeeAmount(fee.Amount) txBuilder.SetGasLimit(fee.GasLimit) - txBuilder.SetTip(tipTx.GetTip()) // Calling SetSignatures with empty sig to populate AuthInfo. - tipperSigsV2, err := tipTx.(authsigning.SigVerifiableTx).GetSignaturesV2() + tipperSigsV2, err := auxSignerData.GetSignatureV2() if err != nil { return nil, err } @@ -208,7 +187,7 @@ func mkFeePayerTxBuilder( SignMode: signMode, Signature: nil, }} - sigsV2 := append(tipperSigsV2, feePayerSigV2) + sigsV2 := append([]signing.SignatureV2{tipperSigsV2}, feePayerSigV2) txBuilder.SetSignatures(sigsV2...) // Actually sign the data. @@ -225,7 +204,7 @@ func mkFeePayerTxBuilder( if err != nil { return nil, err } - sigsV2 = append(tipperSigsV2, feePayerSigV2) + sigsV2 = append([]signing.SignatureV2{tipperSigsV2}, feePayerSigV2) err = txBuilder.SetSignatures(sigsV2...) if err != nil { return nil, err From 28b0bba1319efca2608c4e84fa90cfe377ce0924 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Nov 2021 11:44:36 +0100 Subject: [PATCH 38/40] Less line diff --- x/auth/migrations/legacytx/stdtx_builder.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/auth/migrations/legacytx/stdtx_builder.go b/x/auth/migrations/legacytx/stdtx_builder.go index 9586f3c8b3f2..0c0454034947 100644 --- a/x/auth/migrations/legacytx/stdtx_builder.go +++ b/x/auth/migrations/legacytx/stdtx_builder.go @@ -71,12 +71,12 @@ func (s *StdTxBuilder) SetTimeoutHeight(height uint64) { s.TimeoutHeight = height } -// SetFeePayer does nothing for stdtx -func (s *StdTxBuilder) SetFeePayer(_ sdk.AccAddress) {} - // SetFeeGranter does nothing for stdtx func (s *StdTxBuilder) SetFeeGranter(_ sdk.AccAddress) {} +// SetFeePayer does nothing for stdtx +func (s *StdTxBuilder) SetFeePayer(_ sdk.AccAddress) {} + // AddAuxSignerData returns an error for StdTxBuilder. func (s *StdTxBuilder) AddAuxSignerData(_ tx.AuxSignerData) error { return sdkerrors.ErrLogic.Wrap("cannot use AuxSignerData with StdTxBuilder") From a77181368f97521946cbe0b60d3d996a727baa7a Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Nov 2021 11:51:11 +0100 Subject: [PATCH 39/40] Tweak tests --- x/auth/middleware/tips_test.go | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/x/auth/middleware/tips_test.go b/x/auth/middleware/tips_test.go index 4d6a06614b38..b7f3c9ae8866 100644 --- a/x/auth/middleware/tips_test.go +++ b/x/auth/middleware/tips_test.go @@ -20,10 +20,10 @@ import ( var initialRegens = sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(1000))) var initialAtoms = sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(1000))) -// setupMetaTxAccts sets up 2 accounts: +// setupAcctsForTips sets up 2 accounts: // - tipper has 1000 regens // - feePayer has 1000 atoms and 1000 regens -func (s *MWTestSuite) setupMetaTxAccts(ctx sdk.Context) (sdk.Context, []testAccount) { +func (s *MWTestSuite) setupAcctsForTips(ctx sdk.Context) (sdk.Context, []testAccount) { accts := s.createTestAccounts(ctx, 2, initialRegens) feePayer := accts[1] err := s.app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, initialAtoms) @@ -89,14 +89,13 @@ func (s *MWTestSuite) TestTips() { tc := tc s.Run(tc.name, func() { ctx := s.SetupTest(false) // reset - ctx, accts := s.setupMetaTxAccts(ctx) + ctx, accts := s.setupAcctsForTips(ctx) tipper, feePayer := accts[0], accts[1] msg = govtypes.NewMsgVote(tipper.acc.GetAddress(), 1, govtypes.OptionYes) auxSignerData := s.mkTipperAuxSignerData(tipper.priv, msg, tc.tip, signing.SignMode_SIGN_MODE_DIRECT_AUX, tipper.accNum, 0, ctx.ChainID()) - feePayerTxBuilder, err := mkFeePayerTxBuilder(s.clientCtx, auxSignerData, feePayer.priv, signing.SignMode_SIGN_MODE_DIRECT, tx.Fee{Amount: tc.fee, GasLimit: tc.gasLimit}, feePayer.accNum, 0, ctx.ChainID()) - s.Require().NoError(err) + feePayerTxBuilder := s.mkFeePayerTxBuilder(s.clientCtx, auxSignerData, feePayer.priv, signing.SignMode_SIGN_MODE_DIRECT, tx.Fee{Amount: tc.fee, GasLimit: tc.gasLimit}, feePayer.accNum, 0, ctx.ChainID()) _, res, err := s.app.SimDeliver(s.clientCtx.TxConfig.TxEncoder(), feePayerTxBuilder.GetTx()) @@ -161,26 +160,22 @@ func (s *MWTestSuite) mkTipperAuxSignerData( return auxSignerData } -func mkFeePayerTxBuilder( +func (s *MWTestSuite) mkFeePayerTxBuilder( clientCtx client.Context, auxSignerData tx.AuxSignerData, feePayerPriv cryptotypes.PrivKey, signMode signing.SignMode, fee tx.Fee, accNum, accSeq uint64, chainID string, -) (client.TxBuilder, error) { +) client.TxBuilder { txBuilder := clientCtx.TxConfig.NewTxBuilder() err := txBuilder.AddAuxSignerData(auxSignerData) - if err != nil { - return nil, err - } + s.Require().NoError(err) txBuilder.SetFeePayer(sdk.AccAddress(feePayerPriv.PubKey().Address())) txBuilder.SetFeeAmount(fee.Amount) txBuilder.SetGasLimit(fee.GasLimit) // Calling SetSignatures with empty sig to populate AuthInfo. tipperSigsV2, err := auxSignerData.GetSignatureV2() - if err != nil { - return nil, err - } + s.Require().NoError(err) feePayerSigV2 := signing.SignatureV2{ PubKey: feePayerPriv.PubKey(), Data: &signing.SingleSignatureData{ @@ -201,14 +196,10 @@ func mkFeePayerTxBuilder( feePayerSigV2, err = clienttx.SignWithPrivKey( signMode, signerData, txBuilder, feePayerPriv, clientCtx.TxConfig, accSeq) - if err != nil { - return nil, err - } + s.Require().NoError(err) sigsV2 = append([]signing.SignatureV2{tipperSigsV2}, feePayerSigV2) err = txBuilder.SetSignatures(sigsV2...) - if err != nil { - return nil, err - } + s.Require().NoError(err) - return txBuilder, nil + return txBuilder } From 02a5fe0e8a6f1a24c89533ca114317b5b1348193 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Nov 2021 18:37:36 +0100 Subject: [PATCH 40/40] Rename middleware --- x/auth/middleware/middleware.go | 2 +- x/auth/middleware/tips.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/auth/middleware/middleware.go b/x/auth/middleware/middleware.go index c34ac1832dc8..be8af2176215 100644 --- a/x/auth/middleware/middleware.go +++ b/x/auth/middleware/middleware.go @@ -93,7 +93,7 @@ func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) { ValidateSigCountMiddleware(options.AccountKeeper), SigGasConsumeMiddleware(options.AccountKeeper, sigGasConsumer), SigVerificationMiddleware(options.AccountKeeper, options.SignModeHandler), - NewTipsTxMiddleware(options.BankKeeper), + NewTipMiddleware(options.BankKeeper), IncrementSequenceMiddleware(options.AccountKeeper), ), nil } diff --git a/x/auth/middleware/tips.go b/x/auth/middleware/tips.go index 5716454b3484..bcef9e62e0cd 100644 --- a/x/auth/middleware/tips.go +++ b/x/auth/middleware/tips.go @@ -15,9 +15,9 @@ type tipsTxHandler struct { bankKeeper types.BankKeeper } -// NewTipsTxMiddleware returns a new middleware for handling transactions with +// NewTipMiddleware returns a new middleware for handling transactions with // tips. -func NewTipsTxMiddleware(bankKeeper types.BankKeeper) tx.Middleware { +func NewTipMiddleware(bankKeeper types.BankKeeper) tx.Middleware { return func(txh tx.Handler) tx.Handler { return tipsTxHandler{txh, bankKeeper} }