wormchain: tokenbridge: Use sdk.Coin for transfer fees

Since the transfer amount already uses `sdk.Coin`, use it for fees as
well.  This ensures the fees cannot be negative.

Also add some extra validation for `MsgTransfer` fields and add tests
for the validation checks.
This commit is contained in:
Chirantan Ekbote 2022-08-25 15:35:19 +09:00 committed by Chirantan Ekbote
parent 524520c914
commit ce40d17c74
6 changed files with 165 additions and 76 deletions

View File

@ -47,10 +47,10 @@ message MsgTransfer {
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
uint32 toChain = 3;
bytes toAddress = 4;
string fee = 5;
cosmos.base.v1beta1.Coin fee = 5 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
message MsgTransferResponse {
}
// this line is used by starport scaffolding # proto/tx/message
// this line is used by starport scaffolding # proto/tx/message

View File

@ -3,10 +3,10 @@ package cli
import (
"encoding/hex"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"math/big"
"strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/certusone/wormhole-chain/x/tokenbridge/types"
@ -43,9 +43,9 @@ func CmdTransfer() *cobra.Command {
return fmt.Errorf("to address invalid: %w", err)
}
fee, ok := new(big.Int).SetString(args[3], 10)
if !ok {
return fmt.Errorf("invalid fee (must be a number)")
fee, err := sdk.ParseCoinNormalized(args[3])
if err != nil {
return fmt.Errorf("invalid fee: %w", err)
}
msg := types.NewMsgTransfer(

View File

@ -49,15 +49,9 @@ func (k msgServer) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*typ
}
}
// Parse fees
feeBig, ok := new(big.Int).SetString(msg.Fee, 10)
if !ok || feeBig.Sign() == -1 {
return nil, types.ErrInvalidFee
}
bridgeBalance := new(big.Int).Set(k.bankKeeper.GetBalance(ctx, k.accountKeeper.GetModuleAddress(types.ModuleName), msg.Amount.Denom).Amount.BigInt())
amount := new(big.Int).Set(msg.Amount.Amount.BigInt())
fees := new(big.Int).Set(feeBig)
fees := new(big.Int).Set(msg.Fee.Amount.BigInt())
truncAmount, err := types.Truncate(amount, meta)
if err != nil {

View File

@ -1,7 +1,7 @@
package types
import (
"math/big"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@ -9,13 +9,13 @@ import (
var _ sdk.Msg = &MsgTransfer{}
func NewMsgTransfer(creator string, amount sdk.Coin, toChain uint16, toAddress []byte, fee *big.Int) *MsgTransfer {
func NewMsgTransfer(creator string, amount sdk.Coin, toChain uint16, toAddress []byte, fee sdk.Coin) *MsgTransfer {
return &MsgTransfer{
Creator: creator,
Amount: amount,
ToChain: uint32(toChain),
ToAddress: toAddress,
Fee: fee.String(),
Fee: fee,
}
}
@ -46,17 +46,28 @@ func (msg *MsgTransfer) ValidateBasic() error {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}
err = msg.Amount.Validate()
if err != nil {
return err
if err := msg.Amount.Validate(); err != nil {
return fmt.Errorf("%w: %s", ErrInvalidAmount, err)
}
if msg.ToChain > uint32(^uint16(0)) {
return ErrInvalidTargetChain
}
if len(msg.ToAddress) != 32 {
return ErrInvalidToAddress
}
if _, ok := new(big.Int).SetString(msg.Fee, 10); !ok {
return ErrInvalidFee
if err := msg.Fee.Validate(); err != nil {
return fmt.Errorf("%w: %s", ErrInvalidFee, err)
}
if msg.Amount.Denom != msg.Fee.Denom {
return fmt.Errorf("%w: Fee must have the same denom as Amount", ErrInvalidFee)
}
if msg.Amount.Amount.BigInt().Cmp(msg.Fee.Amount.BigInt()) != 1 {
return ErrFeeTooHigh
}
return nil

View File

@ -1,7 +1,6 @@
package types
import (
"strconv"
"testing"
"github.com/certusone/wormhole-chain/testutil/sample"
@ -27,12 +26,94 @@ func TestMsgTransfer_ValidateBasic(t *testing.T) {
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
ToChain: 1,
ToAddress: make([]byte, 32),
Fee: strconv.Itoa(0),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)),
},
}, {
name: "negative amount",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: sdk.NewInt(-10)},
ToChain: 0,
ToAddress: make([]byte, 32),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0)),
},
err: ErrInvalidAmount,
}, {
name: "invalid amount denom",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.Coin{Denom: "007test", Amount: sdk.NewInt(10)},
ToChain: 0,
ToAddress: make([]byte, 32),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0)),
},
err: ErrInvalidAmount,
}, {
name: "negative fee",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0)),
ToChain: 0,
ToAddress: make([]byte, 32),
Fee: sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: sdk.NewInt(-10)},
},
err: ErrInvalidFee,
}, {
name: "invalid fee denom",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0)),
ToChain: 0,
ToAddress: make([]byte, 32),
Fee: sdk.Coin{Denom: "007test", Amount: sdk.NewInt(10)},
},
err: ErrInvalidFee,
}, {
name: "invalid target chain",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
ToChain: uint32(^uint16(0)) + 1,
ToAddress: make([]byte, 32),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)),
},
err: ErrInvalidTargetChain,
}, {
name: "invalid target address",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
ToChain: 1,
ToAddress: make([]byte, 16),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)),
},
err: ErrInvalidToAddress,
}, {
name: "mismatched denoms",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
ToChain: 1,
ToAddress: make([]byte, 32),
Fee: sdk.NewCoin("test", sdk.NewInt(1)),
},
err: ErrInvalidFee,
}, {
name: "fee too high",
msg: MsgTransfer{
Creator: sample.AccAddress(),
Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
ToChain: 1,
ToAddress: make([]byte, 32),
Fee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)),
},
err: ErrFeeTooHigh,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
err := tt.msg.ValidateBasic()
if tt.err != nil {

View File

@ -298,7 +298,7 @@ type MsgTransfer struct {
Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"`
ToChain uint32 `protobuf:"varint,3,opt,name=toChain,proto3" json:"toChain,omitempty"`
ToAddress []byte `protobuf:"bytes,4,opt,name=toAddress,proto3" json:"toAddress,omitempty"`
Fee string `protobuf:"bytes,5,opt,name=fee,proto3" json:"fee,omitempty"`
Fee types.Coin `protobuf:"bytes,5,opt,name=fee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"fee"`
}
func (m *MsgTransfer) Reset() { *m = MsgTransfer{} }
@ -362,11 +362,11 @@ func (m *MsgTransfer) GetToAddress() []byte {
return nil
}
func (m *MsgTransfer) GetFee() string {
func (m *MsgTransfer) GetFee() types.Coin {
if m != nil {
return m.Fee
}
return ""
return types.Coin{}
}
type MsgTransferResponse struct {
@ -419,39 +419,40 @@ func init() {
func init() { proto.RegisterFile("tokenbridge/tx.proto", fileDescriptor_0276d64dbbd0bb29) }
var fileDescriptor_0276d64dbbd0bb29 = []byte{
// 510 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x41, 0x6f, 0x12, 0x41,
0x14, 0xc7, 0x59, 0x69, 0xab, 0x3c, 0xac, 0x31, 0x2b, 0xb5, 0x2b, 0x31, 0x0b, 0xe2, 0x85, 0x4b,
0x67, 0x5a, 0x7a, 0xd0, 0x58, 0x0f, 0xd2, 0xda, 0x78, 0xe2, 0xe0, 0xa6, 0xf1, 0xe0, 0x6d, 0x59,
0x5e, 0x17, 0x52, 0x77, 0x1e, 0x99, 0x19, 0x10, 0x13, 0x13, 0xbf, 0x82, 0x57, 0xfd, 0x08, 0x7e,
0x92, 0x1e, 0x7b, 0x32, 0x9e, 0xd4, 0xc0, 0x17, 0x31, 0xb3, 0xcb, 0x6e, 0x97, 0xc4, 0x36, 0xa0,
0x27, 0x66, 0xd8, 0xf7, 0xff, 0xbd, 0x37, 0xff, 0xf9, 0x67, 0xa0, 0xa2, 0xe9, 0x0c, 0x45, 0x57,
0x0e, 0x7a, 0x21, 0x72, 0x3d, 0x61, 0x43, 0x49, 0x9a, 0xec, 0xc7, 0x01, 0x4a, 0x3d, 0x52, 0x24,
0x90, 0xbd, 0x27, 0x19, 0xf5, 0xe9, 0x1d, 0x06, 0x7d, 0x7f, 0x20, 0x58, 0xae, 0xba, 0x5a, 0x09,
0x29, 0xa4, 0xb8, 0x9e, 0x9b, 0x55, 0x22, 0xad, 0xba, 0x01, 0xa9, 0x88, 0x14, 0xef, 0xfa, 0x0a,
0xf9, 0x78, 0xaf, 0x8b, 0xda, 0xdf, 0xe3, 0x01, 0x0d, 0x44, 0xf2, 0xbd, 0x71, 0x0c, 0xdb, 0x1d,
0x15, 0x1e, 0x4f, 0x30, 0x18, 0x69, 0x7c, 0x45, 0x63, 0x94, 0xc2, 0x17, 0x01, 0xbe, 0x69, 0xb7,
0x6d, 0x07, 0x6e, 0x06, 0x12, 0x7d, 0x4d, 0xd2, 0xb1, 0xea, 0x56, 0xb3, 0xe4, 0xa5, 0x5b, 0xfb,
0x2e, 0x14, 0xc7, 0xbe, 0xef, 0xdc, 0xa8, 0x5b, 0xcd, 0xdb, 0x9e, 0x59, 0x36, 0x1e, 0x41, 0xed,
0x0a, 0x8c, 0x87, 0x6a, 0x48, 0x42, 0x61, 0xe3, 0x00, 0x36, 0x2f, 0x4b, 0x56, 0xe5, 0x6f, 0xc3,
0xd6, 0x82, 0x38, 0xa3, 0xbe, 0x80, 0x3b, 0x1d, 0x15, 0xb6, 0xb5, 0x46, 0xa5, 0x4f, 0x8c, 0x1b,
0xd7, 0x60, 0x2b, 0xb0, 0xde, 0x43, 0x41, 0x51, 0x0c, 0x2e, 0x79, 0xc9, 0xa6, 0xe1, 0xc0, 0xfd,
0x45, 0x42, 0xc6, 0xfe, 0x6e, 0x41, 0xb9, 0xa3, 0xc2, 0x13, 0xe9, 0x0b, 0x75, 0x8a, 0xf2, 0x1a,
0x72, 0x00, 0x1b, 0x7e, 0x44, 0x23, 0xa1, 0x63, 0x74, 0xb9, 0xf5, 0x80, 0x25, 0xb6, 0x33, 0x63,
0x3b, 0x9b, 0xdb, 0xce, 0x8e, 0x68, 0x20, 0x0e, 0x77, 0xcf, 0x7f, 0xd6, 0x0a, 0xdf, 0x7e, 0xd5,
0x9a, 0xe1, 0x40, 0xf7, 0x47, 0x5d, 0x16, 0x50, 0xc4, 0xe7, 0x77, 0x94, 0xfc, 0xec, 0xa8, 0xde,
0x19, 0xd7, 0x1f, 0x86, 0xa8, 0x62, 0x81, 0xf2, 0xe6, 0x68, 0xd3, 0x5e, 0xd3, 0x91, 0xb9, 0x77,
0xa7, 0x58, 0xb7, 0x9a, 0x9b, 0x5e, 0xba, 0xb5, 0x1f, 0x42, 0x49, 0x53, 0xbb, 0xd7, 0x93, 0xa8,
0x94, 0xb3, 0x16, 0xbb, 0x76, 0xf9, 0x87, 0x71, 0xf3, 0x14, 0xd1, 0x59, 0x8f, 0x47, 0x36, 0xcb,
0xc6, 0x16, 0xdc, 0xcb, 0x9d, 0x2b, 0x3d, 0x6f, 0xeb, 0xcb, 0x1a, 0x14, 0x3b, 0x2a, 0xb4, 0xbf,
0x5a, 0x50, 0xf9, 0x6b, 0x22, 0x9e, 0xb3, 0x25, 0x82, 0xc8, 0xae, 0x08, 0x42, 0xf5, 0xe5, 0xff,
0xa8, 0xd3, 0x21, 0xed, 0x8f, 0x00, 0xb9, 0x0c, 0xb5, 0x56, 0x64, 0x9a, 0x39, 0x9e, 0xad, 0xae,
0xc9, 0xba, 0x7f, 0x82, 0x72, 0x3e, 0x6b, 0xfb, 0xcb, 0xa2, 0x72, 0xa2, 0xea, 0xc1, 0x3f, 0x88,
0xb2, 0x01, 0xc6, 0x70, 0x2b, 0xcb, 0xe3, 0xee, 0xb2, 0xa0, 0x54, 0x51, 0x7d, 0xba, 0xaa, 0x22,
0xed, 0x7b, 0xf8, 0xfa, 0x7c, 0xea, 0x5a, 0x17, 0x53, 0xd7, 0xfa, 0x3d, 0x75, 0xad, 0xcf, 0x33,
0xb7, 0x70, 0x31, 0x73, 0x0b, 0x3f, 0x66, 0x6e, 0xe1, 0xed, 0x93, 0x7c, 0x90, 0x53, 0x3a, 0x4f,
0xe9, 0x3b, 0x31, 0x9e, 0x4f, 0xf8, 0xc2, 0xc3, 0x66, 0xd2, 0xdd, 0xdd, 0x88, 0x5f, 0xa0, 0xfd,
0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x47, 0xfa, 0x12, 0x3e, 0xf4, 0x04, 0x00, 0x00,
// 513 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x31, 0x6f, 0xd3, 0x40,
0x14, 0xc7, 0xe3, 0xa6, 0x2d, 0xe4, 0x85, 0x22, 0x64, 0x52, 0x6a, 0x22, 0xe4, 0x84, 0xb0, 0x64,
0xe9, 0x5d, 0x9b, 0x0e, 0x20, 0xca, 0x40, 0x5a, 0x2a, 0xa6, 0x0c, 0x58, 0x15, 0x03, 0x12, 0x83,
0xe3, 0xbc, 0x3a, 0x56, 0xf1, 0xbd, 0xe8, 0xee, 0x12, 0x82, 0x84, 0xc4, 0x57, 0x60, 0x85, 0x95,
0x8d, 0x4f, 0xd2, 0xb1, 0x23, 0x13, 0xa0, 0xe4, 0x8b, 0x20, 0xdb, 0xb1, 0xeb, 0x48, 0xb4, 0x4a,
0xa0, 0x53, 0xee, 0xc5, 0xef, 0xff, 0x7b, 0x4f, 0xff, 0xfb, 0xeb, 0xa0, 0xa2, 0xe9, 0x14, 0x45,
0x57, 0x06, 0x3d, 0x1f, 0xb9, 0x1e, 0xb3, 0x81, 0x24, 0x4d, 0xe6, 0x23, 0x0f, 0xa5, 0x1e, 0x2a,
0x12, 0xc8, 0xde, 0x93, 0x0c, 0xfb, 0xf4, 0x0e, 0xbd, 0xbe, 0x1b, 0x08, 0x96, 0xeb, 0xae, 0x56,
0x7c, 0xf2, 0x29, 0xee, 0xe7, 0xd1, 0x29, 0x91, 0x56, 0x6d, 0x8f, 0x54, 0x48, 0x8a, 0x77, 0x5d,
0x85, 0x7c, 0xb4, 0xdb, 0x45, 0xed, 0xee, 0x72, 0x8f, 0x02, 0x91, 0x7c, 0x6f, 0x1c, 0xc1, 0x56,
0x47, 0xf9, 0x47, 0x63, 0xf4, 0x86, 0x1a, 0x5f, 0xd2, 0x08, 0xa5, 0x70, 0x85, 0x87, 0xaf, 0xdb,
0x6d, 0xd3, 0x82, 0x1b, 0x9e, 0x44, 0x57, 0x93, 0xb4, 0x8c, 0xba, 0xd1, 0x2c, 0x39, 0x69, 0x69,
0xde, 0x81, 0xe2, 0xc8, 0x75, 0xad, 0x95, 0xba, 0xd1, 0xbc, 0xe5, 0x44, 0xc7, 0xc6, 0x43, 0xa8,
0x5d, 0x82, 0x71, 0x50, 0x0d, 0x48, 0x28, 0x6c, 0xec, 0xc3, 0xc6, 0x45, 0xcb, 0xb2, 0xfc, 0x2d,
0xd8, 0x9c, 0x13, 0x67, 0xd4, 0xe7, 0x70, 0xbb, 0xa3, 0xfc, 0xb6, 0xd6, 0xa8, 0xf4, 0x71, 0xe4,
0xc6, 0x15, 0xd8, 0x0a, 0xac, 0xf5, 0x50, 0x50, 0x18, 0x83, 0x4b, 0x4e, 0x52, 0x34, 0x2c, 0xb8,
0x37, 0x4f, 0xc8, 0xd8, 0xdf, 0x56, 0xa0, 0xdc, 0x51, 0xfe, 0xb1, 0x74, 0x85, 0x3a, 0x41, 0x79,
0x05, 0xd9, 0x83, 0x75, 0x37, 0xa4, 0xa1, 0xd0, 0x31, 0xba, 0xdc, 0xba, 0xcf, 0x12, 0xdb, 0x59,
0x64, 0x3b, 0x9b, 0xd9, 0xce, 0x0e, 0x29, 0x10, 0x07, 0x3b, 0x67, 0x3f, 0x6b, 0x85, 0xef, 0xbf,
0x6a, 0x4d, 0x3f, 0xd0, 0xfd, 0x61, 0x97, 0x79, 0x14, 0xf2, 0xd9, 0x1d, 0x25, 0x3f, 0xdb, 0xaa,
0x77, 0xca, 0xf5, 0x87, 0x01, 0xaa, 0x58, 0xa0, 0x9c, 0x19, 0x3a, 0x1a, 0xaf, 0xe9, 0x30, 0xba,
0x77, 0xab, 0x58, 0x37, 0x9a, 0x1b, 0x4e, 0x5a, 0x9a, 0x0f, 0xa0, 0xa4, 0xa9, 0xdd, 0xeb, 0x49,
0x54, 0xca, 0x5a, 0x8d, 0x5d, 0xbb, 0xf8, 0xc3, 0x7c, 0x0b, 0xc5, 0x13, 0x44, 0x6b, 0xed, 0xfa,
0x37, 0x8b, 0xb8, 0x8d, 0x4d, 0xb8, 0x9b, 0x33, 0x29, 0x35, 0xaf, 0xf5, 0x65, 0x15, 0x8a, 0x1d,
0xe5, 0x9b, 0x5f, 0x0d, 0xa8, 0xfc, 0x35, 0x5e, 0xcf, 0xd8, 0x02, 0xa9, 0x66, 0x97, 0xa4, 0xaa,
0xfa, 0xe2, 0x7f, 0xd4, 0xe9, 0x92, 0xe6, 0x47, 0x80, 0x5c, 0x20, 0x5b, 0x4b, 0x32, 0xa3, 0x3d,
0x9e, 0x2e, 0xaf, 0xc9, 0xa6, 0x7f, 0x82, 0x72, 0x3e, 0xb8, 0x7b, 0x8b, 0xa2, 0x72, 0xa2, 0xea,
0xfe, 0x3f, 0x88, 0xb2, 0x05, 0x46, 0x70, 0x33, 0x0b, 0xf7, 0xce, 0xa2, 0xa0, 0x54, 0x51, 0x7d,
0xb2, 0xac, 0x22, 0x9d, 0x7b, 0xf0, 0xea, 0x6c, 0x62, 0x1b, 0xe7, 0x13, 0xdb, 0xf8, 0x3d, 0xb1,
0x8d, 0xcf, 0x53, 0xbb, 0x70, 0x3e, 0xb5, 0x0b, 0x3f, 0xa6, 0x76, 0xe1, 0xcd, 0xe3, 0x7c, 0xf6,
0x52, 0x3a, 0x4f, 0xe9, 0xdb, 0x31, 0x9e, 0x8f, 0xf9, 0xdc, 0x2b, 0x19, 0x05, 0xb2, 0xbb, 0x1e,
0x3f, 0x67, 0x7b, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x8b, 0x37, 0x29, 0x41, 0x05, 0x00,
0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -842,13 +843,16 @@ func (m *MsgTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.Fee) > 0 {
i -= len(m.Fee)
copy(dAtA[i:], m.Fee)
i = encodeVarintTx(dAtA, i, uint64(len(m.Fee)))
i--
dAtA[i] = 0x2a
{
size, err := m.Fee.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTx(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
if len(m.ToAddress) > 0 {
i -= len(m.ToAddress)
copy(dAtA[i:], m.ToAddress)
@ -1012,10 +1016,8 @@ func (m *MsgTransfer) Size() (n int) {
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
l = len(m.Fee)
if l > 0 {
n += 1 + l + sovTx(uint64(l))
}
l = m.Fee.Size()
n += 1 + l + sovTx(uint64(l))
return n
}
@ -1681,7 +1683,7 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType)
}
var stringLen uint64
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
@ -1691,23 +1693,24 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
if msglen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + intStringLen
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Fee = string(dAtA[iNdEx:postIndex])
if err := m.Fee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex