diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 89dc49f12f7..96ee2ea6757 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -3144,6 +3144,16 @@ MsgChannelUpgradeConfirmResponse defines the MsgChannelUpgradeConfirm response t MsgChanelUpgradeInit defines the request type for the ChannelUpgradeInit rpc +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `port_id` | [string](#string) | | | +| `channel_id` | [string](#string) | | | +| `proposed_upgrade_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | +| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | +| `timeout_timestamp` | [uint64](#uint64) | | | +| `signer` | [string](#string) | | | + + diff --git a/modules/core/04-channel/types/msgs.go b/modules/core/04-channel/types/msgs.go index cf3ba16111a..0f2bf9d8449 100644 --- a/modules/core/04-channel/types/msgs.go +++ b/modules/core/04-channel/types/msgs.go @@ -499,18 +499,53 @@ var _ sdk.Msg = &MsgChannelUpgradeInit{} // NewMsgChannelUpgradeInit constructs a new MsgChannelUpgradeInit // nolint:interfacer -func NewMsgChannelUpgradeInit() *MsgChannelUpgradeInit { - return &MsgChannelUpgradeInit{} +func NewMsgChannelUpgradeInit( + portID, channelID string, + proposedUpgradeChannel Channel, + TimeoutHeight clienttypes.Height, + TimeoutTimestamp uint64, + signer string, +) *MsgChannelUpgradeInit { + return &MsgChannelUpgradeInit{ + PortId: portID, + ChannelId: channelID, + ProposedUpgradeChannel: proposedUpgradeChannel, + TimeoutHeight: TimeoutHeight, + TimeoutTimestamp: TimeoutTimestamp, + Signer: signer, + } } // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeInit) ValidateBasic() error { - return errors.New("error method not implemented") + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return sdkerrors.Wrap(err, "invalid port ID") + } + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + if msg.ProposedUpgradeChannel.State != INITUPGRADE { + return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", INITUPGRADE, msg.ProposedUpgradeChannel.State) + } + if msg.TimeoutHeight.IsZero() && msg.TimeoutTimestamp == 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeTimeout, "timeout height and timeout timestamp cannot both be 0") + } + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return nil } // GetSigners implements sdk.Msg func (msg MsgChannelUpgradeInit) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{} + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{signer} } var _ sdk.Msg = &MsgChannelUpgradeTry{} diff --git a/modules/core/04-channel/types/msgs_test.go b/modules/core/04-channel/types/msgs_test.go index 44de2450c0c..b72d9dba14d 100644 --- a/modules/core/04-channel/types/msgs_test.go +++ b/modules/core/04-channel/types/msgs_test.go @@ -437,6 +437,80 @@ func (suite *TypesTestSuite) TestMsgAcknowledgementValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelUpgradeInitValidateBasic() { + var msg *types.MsgChannelUpgradeInit + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "invalid proposed upgrade channel state", + func() { + msg.ProposedUpgradeChannel.State = types.TRYUPGRADE + }, + false, + }, + { + "timeout height is zero && timeout timestamp is zero", + func() { + msg.TimeoutHeight = clienttypes.ZeroHeight() + msg.TimeoutTimestamp = 0 + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeInit( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.Channel{State: types.INITUPGRADE}, + clienttypes.NewHeight(0, 10000), + 0, + addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + func (suite *TypesTestSuite) TestMsgChannelUpgradeTryValidateBasic() { var msg *types.MsgChannelUpgradeTry diff --git a/modules/core/04-channel/types/tx.pb.go b/modules/core/04-channel/types/tx.pb.go index 582632c979b..c2f814943d9 100644 --- a/modules/core/04-channel/types/tx.pb.go +++ b/modules/core/04-channel/types/tx.pb.go @@ -892,6 +892,12 @@ var xxx_messageInfo_MsgAcknowledgementResponse proto.InternalMessageInfo // MsgChanelUpgradeInit defines the request type for the ChannelUpgradeInit rpc type MsgChannelUpgradeInit struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` + ProposedUpgradeChannel Channel `protobuf:"bytes,3,opt,name=proposed_upgrade_channel,json=proposedUpgradeChannel,proto3" json:"proposed_upgrade_channel" yaml:"proposed_upgrade_channel"` + TimeoutHeight types.Height `protobuf:"bytes,4,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height" yaml:"timeout_height"` + TimeoutTimestamp uint64 `protobuf:"varint,5,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty" yaml:"timeout_timestamp"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelUpgradeInit) Reset() { *m = MsgChannelUpgradeInit{} } @@ -3087,6 +3093,52 @@ func (m *MsgChannelUpgradeInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + if m.TimeoutTimestamp != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TimeoutTimestamp)) + i-- + dAtA[i] = 0x28 + } + { + size, err := m.TimeoutHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.ProposedUpgradeChannel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0x12 + } + if len(m.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -3991,6 +4043,25 @@ func (m *MsgChannelUpgradeInit) Size() (n int) { } var l int _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProposedUpgradeChannel.Size() + n += 1 + l + sovTx(uint64(l)) + l = m.TimeoutHeight.Size() + n += 1 + l + sovTx(uint64(l)) + if m.TimeoutTimestamp != 0 { + n += 1 + sovTx(uint64(m.TimeoutTimestamp)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -7018,6 +7089,187 @@ func (m *MsgChannelUpgradeInit) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgChannelUpgradeInit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PortId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposedUpgradeChannel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ProposedUpgradeChannel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutHeight", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TimeoutHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + m.TimeoutTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeoutTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index ba49835a1d9..36c3ad8fb7b 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -267,6 +267,15 @@ message MsgAcknowledgementResponse { message MsgChannelUpgradeInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + Channel proposed_upgrade_channel = 3 + [(gogoproto.moretags) = "yaml:\"proposed_upgrade_channel\"", (gogoproto.nullable) = false]; + ibc.core.client.v1.Height timeout_height = 4 + [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + uint64 timeout_timestamp = 5 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + string signer = 6; } // MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type