diff --git a/go.mod b/go.mod index 4dc43fcd1d1..de7e5bbcd96 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,6 @@ require ( ) require ( - github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.6.1 // indirect cloud.google.com/go/iam v0.3.0 // indirect @@ -131,6 +130,7 @@ require ( github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/ulikunitz/xz v0.5.8 // indirect + github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect diff --git a/modules/apps/27-interchain-accounts/controller/types/msgs.go b/modules/apps/27-interchain-accounts/controller/types/msgs.go index 9033df4bc3c..fec761e2123 100644 --- a/modules/apps/27-interchain-accounts/controller/types/msgs.go +++ b/modules/apps/27-interchain-accounts/controller/types/msgs.go @@ -1,9 +1,16 @@ package types import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + host "github.com/cosmos/ibc-go/v5/modules/core/24-host" ) +var _ sdk.Msg = &MsgRegisterAccount{} + // NewMsgRegisterAccount creates a new instance of MsgRegisterAccount func NewMsgRegisterAccount(connectionID, owner, version string) *MsgRegisterAccount { return &MsgRegisterAccount{ @@ -15,10 +22,27 @@ func NewMsgRegisterAccount(connectionID, owner, version string) *MsgRegisterAcco // ValidateBasic implements sdk.Msg func (msg MsgRegisterAccount) ValidateBasic() error { + if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { + return sdkerrors.Wrap(err, "invalid connection ID") + } + + if strings.TrimSpace(msg.Owner) == "" { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner address cannot be empty") + } + + if _, err := sdk.AccAddressFromBech32(msg.Owner); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "failed to parse owner address: %s", msg.Owner) + } + return nil } // GetSigners implements sdk.Msg func (msg MsgRegisterAccount) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{} + accAddr, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{accAddr} } diff --git a/modules/apps/27-interchain-accounts/controller/types/msgs_test.go b/modules/apps/27-interchain-accounts/controller/types/msgs_test.go new file mode 100644 index 00000000000..1fdd4f338a6 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/types/msgs_test.go @@ -0,0 +1,96 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types" + feetypes "github.com/cosmos/ibc-go/v5/modules/apps/29-fee/types" + ibctesting "github.com/cosmos/ibc-go/v5/testing" +) + +func TestMsgRegisterAccountValidateBasic(t *testing.T) { + var msg *types.MsgRegisterAccount + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: with empty channel version", + func() { + msg.Version = "" + }, + true, + }, + { + "success: with fee enabled channel version", + func() { + feeMetadata := feetypes.Metadata{ + FeeVersion: feetypes.Version, + AppVersion: icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID), + } + + bz := feetypes.ModuleCdc.MustMarshalJSON(&feeMetadata) + msg.Version = string(bz) + }, + true, + }, + { + "connection id is invalid", + func() { + msg.ConnectionId = "" + }, + false, + }, + { + "owner address is empty", + func() { + msg.Owner = "" + }, + false, + }, + { + "owner address is invalid", + func() { + msg.Owner = "invalid_address" + }, + false, + }, + } + + for i, tc := range testCases { + + msg = types.NewMsgRegisterAccount( + ibctesting.FirstConnectionID, + ibctesting.TestAccAddress, + icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID), + ) + + tc.malleate() + + err := msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func TestMsgRegisterAccountGetSigners(t *testing.T) { + expSigner, err := sdk.AccAddressFromBech32(ibctesting.TestAccAddress) + require.NoError(t, err) + + msg := types.NewMsgRegisterAccount(ibctesting.FirstConnectionID, ibctesting.TestAccAddress, "") + require.Equal(t, []sdk.AccAddress{expSigner}, msg.GetSigners()) +} diff --git a/testing/values.go b/testing/values.go index 46df3b5ba27..fa626009f4a 100644 --- a/testing/values.go +++ b/testing/values.go @@ -48,7 +48,9 @@ var ( // DefaultTrustLevel sets params variables used to create a TM client DefaultTrustLevel = ibctmtypes.DefaultTrustLevel - TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + + TestAccAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) UpgradePath = []string{"upgrade", "upgradedIBCState"}