Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x/tx/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Since v0.13.0, x/tx follows Cosmos SDK semver: https://github.com/cosmos/cosmos-
* [#21782](https://github.com/cosmos/cosmos-sdk/pull/21782) Fix JSON attribute sort order on messages with oneof fields.
* [#21825](https://github.com/cosmos/cosmos-sdk/pull/21825) Fix decimal encoding and field ordering in Amino JSON encoder.
* [#21850](https://github.com/cosmos/cosmos-sdk/pull/21850) Support bytes field as signer.
* [#22311](https://github.com/cosmos/cosmos-sdk/pull/22311) Fix add feePayer as signer.

## [v0.13.5](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.5) - 2024-09-18

Expand Down
12 changes: 12 additions & 0 deletions x/tx/decode/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
}
}

// If a fee payer is specified in the AuthInfo, it must be added to the list of signers
if authInfo.Fee != nil && authInfo.Fee.Payer != "" {
feeAddr, err := d.signingCtx.AddressCodec().StringToBytes(authInfo.Fee.Payer)
if err != nil {
return nil, errorsmod.Wrap(ErrTxDecode, err.Error())
}

if _, seen := seenSigners[string(feeAddr)]; !seen {
signers = append(signers, feeAddr)
}
}

return &DecodedTx{
Messages: msgs,
DynamicMessages: dynamicMsgs,
Expand Down
86 changes: 72 additions & 14 deletions x/tx/decode/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,84 @@ func TestDecode(t *testing.T) {
gogoproto.RegisterType(&testpb.A{}, string((&testpb.A{}).ProtoReflect().Descriptor().FullName()))

testCases := []struct {
name string
msg proto.Message
error string
name string
msg proto.Message
authInfo *txv1beta1.AuthInfo
error string
numSigners int
}{
{
name: "happy path",
msg: &bankv1beta1.MsgSend{},
authInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "",
Granter: "",
},
},
numSigners: 1,
},
{
name: "empty signer option",
msg: &testpb.A{},
name: "empty signer option",
msg: &testpb.A{},
authInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "",
Granter: "",
},
},
error: "no cosmos.msg.v1.signer option found for message A; use DefineCustomGetSigners to specify a custom getter: tx parse error",
},
{
name: "invalid feePayer",
msg: &bankv1beta1.MsgSend{},
authInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "payer",
Granter: "",
},
},
error: `encoding/hex: invalid byte: U+0070 'p': tx parse error`,
},
{
name: "valid feePayer",
msg: &bankv1beta1.MsgSend{},
authInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "636f736d6f733168363935356b3836397a72306770383975717034337a373263393033666d35647a366b75306c", // hexadecimal to work with dummyAddressCodec
Granter: "",
},
},
numSigners: 2,
},
{
name: "same msg signer and feePayer",
msg: &bankv1beta1.MsgSend{
FromAddress: "636f736d6f733168363935356b3836397a72306770383975717034337a373263393033666d35647a366b75306c",
},
authInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "636f736d6f733168363935356b3836397a72306770383975717034337a373263393033666d35647a366b75306c",
Granter: "",
},
},
numSigners: 1,
},
}

for _, tc := range testCases {
Expand All @@ -89,15 +154,7 @@ func TestDecode(t *testing.T) {
Memo: "memo",
TimeoutHeight: 0,
},
AuthInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "payer",
Granter: "",
},
},
AuthInfo: tc.authInfo,
Signatures: nil,
}
txBytes, err := proto.Marshal(tx)
Expand All @@ -109,6 +166,7 @@ func TestDecode(t *testing.T) {
return
}
require.NoError(t, err)
require.Equal(t, len(decodeTx.Signers), tc.numSigners)

require.Equal(t,
fmt.Sprintf("/%s", tc.msg.ProtoReflect().Descriptor().FullName()),
Expand Down