From 5cc249e08a4ec9fc7cef037aefd7626f73d7bc84 Mon Sep 17 00:00:00 2001 From: Carlos Rodriguez Date: Thu, 10 Mar 2022 12:15:11 +0100 Subject: [PATCH] replace channel keeper with IBC keeper in AnteDecorator (#950) * replace channel keeper with IBC keeper in AnteDecorator and pass message to rpc handler * fix error checking condition * fix for proper way of getting go context * refactor tests for ante handler * review comment * review comments and some fixes * review comments * execute message for update client as well * add migration Co-authored-by: Carlos Rodriguez (cherry picked from commit f0b94dfa992d0baf777d9fb3d5ac896d543a8a4e) --- CHANGELOG.md | 1 + docs/ibc/proto-docs.md | 35 ++ docs/migrations/v2-to-v3.md | 16 + modules/core/04-channel/types/tx.pb.go | 299 ++++++++++--- modules/core/ante/ante.go | 45 +- modules/core/ante/ante_test.go | 595 +++++++++++++------------ modules/core/keeper/msg_server.go | 16 +- proto/ibc/core/channel/v1/tx.proto | 36 +- testing/endpoint.go | 30 ++ testing/simapp/ante_handler.go | 9 +- testing/simapp/app.go | 2 +- 11 files changed, 683 insertions(+), 401 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 969fedc24f0..0629d3ebf13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (testing) [\#776](https://github.com/cosmos/ibc-go/pull/776) Adding helper fn to generate capability name for testing callbacks * (testing) [\#892](https://github.com/cosmos/ibc-go/pull/892) IBC Mock modules store the scoped keeper and portID within the IBCMockApp. They also maintain reference to the AppModule to update the AppModule's list of IBC applications it references. Allows for the mock module to be reused as a base application in middleware stacks. * (channel) [\#882](https://github.com/cosmos/ibc-go/pull/882) The `WriteAcknowledgement` API now takes `exported.Acknowledgement` instead of a byte array +* (modules/core/ante) [\#950](https://github.com/cosmos/ibc-go/pull/950) Replaces the channel keeper with the IBC keeper in the IBC `AnteDecorator` in order to execute the entire message and be able to reject redundant messages that are in the same block as the non-redundant messages. ### State Machine Breaking diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 79d56a6a541..80b2df196d3 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -127,6 +127,8 @@ - [MsgTimeoutOnCloseResponse](#ibc.core.channel.v1.MsgTimeoutOnCloseResponse) - [MsgTimeoutResponse](#ibc.core.channel.v1.MsgTimeoutResponse) + - [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) + - [Msg](#ibc.core.channel.v1.Msg) - [ibc/core/client/v1/genesis.proto](#ibc/core/client/v1/genesis.proto) @@ -1738,6 +1740,11 @@ MsgAcknowledgement receives incoming IBC acknowledgement MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | + + @@ -1954,6 +1961,11 @@ MsgRecvPacket receives incoming IBC packet MsgRecvPacketResponse defines the Msg/RecvPacket response type. +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | + + @@ -2003,6 +2015,11 @@ MsgTimeoutOnClose timed-out packet upon counterparty channel closure. MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | + + @@ -2013,11 +2030,29 @@ MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. MsgTimeoutResponse defines the Msg/Timeout response type. +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | + + + + + +### ResponseResultType +ResponseResultType defines the possible outcomes of the execution of a message + +| Name | Number | Description | +| ---- | ------ | ----------- | +| RESPONSE_RESULT_UNSPECIFIED | 0 | Default zero value enumeration | +| RESPONSE_RESULT_NOOP | 1 | The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) | +| RESPONSE_RESULT_SUCCESS | 2 | The message was executed successfully | + + diff --git a/docs/migrations/v2-to-v3.md b/docs/migrations/v2-to-v3.md index 30550d9be04..37224134b6b 100644 --- a/docs/migrations/v2-to-v3.md +++ b/docs/migrations/v2-to-v3.md @@ -109,6 +109,22 @@ The migration code required may look like: appState[icatypes.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(icaGenesisState) ``` +### Ante decorator + +The field of type `channelkeeper.Keeper` in the `AnteDecorator` structure has been replaced with a field of type `*keeper.Keeper`: + +```diff +type AnteDecorator struct { +- k channelkeeper.Keeper ++ k *keeper.Keeper +} + +- func NewAnteDecorator(k channelkeeper.Keeper) AnteDecorator { ++ func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { + return AnteDecorator{k: k} +} +``` + ## IBC Apps diff --git a/modules/core/04-channel/types/tx.pb.go b/modules/core/04-channel/types/tx.pb.go index 6fcc1a44276..e497cf802b1 100644 --- a/modules/core/04-channel/types/tx.pb.go +++ b/modules/core/04-channel/types/tx.pb.go @@ -29,6 +29,38 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// ResponseResultType defines the possible outcomes of the execution of a message +type ResponseResultType int32 + +const ( + // Default zero value enumeration + UNSPECIFIED ResponseResultType = 0 + // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) + NOOP ResponseResultType = 1 + // The message was executed successfully + SUCCESS ResponseResultType = 2 +) + +var ResponseResultType_name = map[int32]string{ + 0: "RESPONSE_RESULT_UNSPECIFIED", + 1: "RESPONSE_RESULT_NOOP", + 2: "RESPONSE_RESULT_SUCCESS", +} + +var ResponseResultType_value = map[string]int32{ + "RESPONSE_RESULT_UNSPECIFIED": 0, + "RESPONSE_RESULT_NOOP": 1, + "RESPONSE_RESULT_SUCCESS": 2, +} + +func (x ResponseResultType) String() string { + return proto.EnumName(ResponseResultType_name, int32(x)) +} + +func (ResponseResultType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{0} +} + // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. type MsgChannelOpenInit struct { @@ -566,6 +598,7 @@ var xxx_messageInfo_MsgRecvPacket proto.InternalMessageInfo // MsgRecvPacketResponse defines the Msg/RecvPacket response type. type MsgRecvPacketResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } func (m *MsgRecvPacketResponse) Reset() { *m = MsgRecvPacketResponse{} } @@ -645,6 +678,7 @@ var xxx_messageInfo_MsgTimeout proto.InternalMessageInfo // MsgTimeoutResponse defines the Msg/Timeout response type. type MsgTimeoutResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } func (m *MsgTimeoutResponse) Reset() { *m = MsgTimeoutResponse{} } @@ -725,6 +759,7 @@ var xxx_messageInfo_MsgTimeoutOnClose proto.InternalMessageInfo // MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. type MsgTimeoutOnCloseResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } func (m *MsgTimeoutOnCloseResponse) Reset() { *m = MsgTimeoutOnCloseResponse{} } @@ -804,6 +839,7 @@ var xxx_messageInfo_MsgAcknowledgement proto.InternalMessageInfo // MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. type MsgAcknowledgementResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } func (m *MsgAcknowledgementResponse) Reset() { *m = MsgAcknowledgementResponse{} } @@ -840,6 +876,7 @@ func (m *MsgAcknowledgementResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAcknowledgementResponse proto.InternalMessageInfo func init() { + proto.RegisterEnum("ibc.core.channel.v1.ResponseResultType", ResponseResultType_name, ResponseResultType_value) proto.RegisterType((*MsgChannelOpenInit)(nil), "ibc.core.channel.v1.MsgChannelOpenInit") proto.RegisterType((*MsgChannelOpenInitResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenInitResponse") proto.RegisterType((*MsgChannelOpenTry)(nil), "ibc.core.channel.v1.MsgChannelOpenTry") @@ -865,79 +902,87 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1138 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0xdb, 0x46, - 0x13, 0xd6, 0x87, 0x2d, 0xdb, 0x63, 0xbf, 0xb1, 0x4d, 0xf9, 0x43, 0xa1, 0x6c, 0xd1, 0x2f, 0x0f, - 0x89, 0x91, 0x22, 0x62, 0x6c, 0x07, 0x28, 0x12, 0xf4, 0x62, 0x09, 0x28, 0x6a, 0x14, 0x6e, 0x0a, - 0xda, 0xed, 0xc1, 0x28, 0x20, 0x48, 0xab, 0x0d, 0x45, 0x48, 0xe2, 0xaa, 0x24, 0xa5, 0x44, 0xff, - 0xa0, 0xc7, 0x9c, 0x7b, 0x4a, 0xcf, 0x3d, 0xa4, 0x3f, 0x23, 0xc7, 0x9c, 0xda, 0xa2, 0x07, 0xa2, - 0xb0, 0x2f, 0x3d, 0xf3, 0x17, 0x14, 0x5c, 0x2e, 0x3f, 0x24, 0x91, 0x15, 0x95, 0x54, 0x6e, 0x6e, - 0xe4, 0xcc, 0xb3, 0xb3, 0xb3, 0xcf, 0x33, 0x9c, 0xdd, 0x25, 0xec, 0xa9, 0x0d, 0x24, 0x21, 0xa2, - 0x63, 0x09, 0xb5, 0xea, 0x9a, 0x86, 0x3b, 0xd2, 0xe0, 0x48, 0x32, 0x5f, 0x96, 0x7b, 0x3a, 0x31, - 0x09, 0x97, 0x57, 0x1b, 0xa8, 0xec, 0x78, 0xcb, 0xcc, 0x5b, 0x1e, 0x1c, 0xf1, 0x5b, 0x0a, 0x51, - 0x08, 0xf5, 0x4b, 0xce, 0x93, 0x0b, 0xe5, 0x85, 0x20, 0x50, 0x47, 0xc5, 0x9a, 0xe9, 0xc4, 0x71, - 0x9f, 0x18, 0xe0, 0xff, 0x51, 0x33, 0x79, 0x61, 0x29, 0x44, 0xfc, 0x29, 0x0d, 0xdc, 0xb9, 0xa1, - 0x54, 0x5d, 0xe3, 0xb3, 0x1e, 0xd6, 0xce, 0x34, 0xd5, 0xe4, 0x3e, 0x81, 0xa5, 0x1e, 0xd1, 0xcd, - 0x9a, 0xda, 0x2c, 0xa4, 0x0f, 0xd2, 0x87, 0x2b, 0x15, 0xce, 0xb6, 0x84, 0x3b, 0xc3, 0x7a, 0xb7, - 0xf3, 0x54, 0x64, 0x0e, 0x51, 0xce, 0x39, 0x4f, 0x67, 0x4d, 0xee, 0x33, 0x58, 0x62, 0x41, 0x0b, - 0x99, 0x83, 0xf4, 0xe1, 0xea, 0xf1, 0x5e, 0x39, 0x62, 0x11, 0x65, 0x36, 0x47, 0x65, 0xe1, 0xad, - 0x25, 0xa4, 0x64, 0x6f, 0x08, 0xb7, 0x03, 0x39, 0x43, 0x55, 0x34, 0xac, 0x17, 0xb2, 0xce, 0x4c, - 0x32, 0x7b, 0x7b, 0xba, 0xfc, 0xc3, 0x6b, 0x21, 0xf5, 0xd7, 0x6b, 0x21, 0x25, 0xca, 0xc0, 0x4f, - 0xa6, 0x28, 0x63, 0xa3, 0x47, 0x34, 0x03, 0x73, 0x8f, 0x01, 0x58, 0xa8, 0x20, 0xdb, 0x6d, 0xdb, - 0x12, 0x36, 0xdd, 0x6c, 0x03, 0x9f, 0x28, 0xaf, 0xb0, 0x97, 0xb3, 0xa6, 0xf8, 0x6b, 0x16, 0x36, - 0x47, 0x83, 0x5e, 0xea, 0xc3, 0xd9, 0x96, 0xfd, 0x15, 0xe4, 0x7b, 0x3a, 0x1e, 0xa8, 0xa4, 0x6f, - 0xd4, 0x42, 0x19, 0x64, 0xe8, 0xc0, 0x92, 0x6d, 0x09, 0x3c, 0x1b, 0x38, 0x09, 0x12, 0xe5, 0x4d, - 0xcf, 0x5a, 0xf5, 0x52, 0x0a, 0xd3, 0x98, 0x9d, 0x9d, 0x46, 0x19, 0xb6, 0x10, 0xe9, 0x6b, 0x26, - 0xd6, 0x7b, 0x75, 0xdd, 0x1c, 0xd6, 0x06, 0x58, 0x37, 0x54, 0xa2, 0x15, 0x16, 0x68, 0x3a, 0x82, - 0x6d, 0x09, 0x45, 0x46, 0x48, 0x04, 0x4a, 0x94, 0xf3, 0x61, 0xf3, 0xb7, 0xae, 0xd5, 0xa1, 0xb6, - 0xa7, 0x13, 0xf2, 0xbc, 0xa6, 0x6a, 0xaa, 0x59, 0x58, 0x3c, 0x48, 0x1f, 0xae, 0x85, 0xa9, 0x0d, - 0x7c, 0xa2, 0xbc, 0x42, 0x5f, 0x68, 0xed, 0x5c, 0xc1, 0x9a, 0xeb, 0x69, 0x61, 0x55, 0x69, 0x99, - 0x85, 0x1c, 0x5d, 0x0c, 0x1f, 0x5a, 0x8c, 0x5b, 0xa3, 0x83, 0xa3, 0xf2, 0x17, 0x14, 0x51, 0x29, - 0x3a, 0x4b, 0xb1, 0x2d, 0x21, 0x1f, 0x8e, 0xeb, 0x8e, 0x16, 0xe5, 0x55, 0xfa, 0xea, 0x22, 0x43, - 0xc5, 0xb2, 0x14, 0x53, 0x2c, 0x45, 0xb8, 0x3b, 0xa1, 0xab, 0x57, 0x2b, 0xe2, 0x6f, 0x13, 0xaa, - 0x9f, 0xa2, 0xf6, 0x6c, 0xaa, 0x8f, 0x96, 0x5b, 0x26, 0x59, 0xb9, 0x71, 0x57, 0xb0, 0x3b, 0xc2, - 0x7b, 0x28, 0x04, 0xad, 0xfa, 0x8a, 0x68, 0x5b, 0x42, 0x29, 0x42, 0xa0, 0x70, 0xbc, 0xed, 0xb0, - 0x27, 0xa8, 0x9b, 0x79, 0x28, 0x7f, 0x04, 0xae, 0xa0, 0x35, 0x53, 0x1f, 0x32, 0xe1, 0xb7, 0x6c, - 0x4b, 0xd8, 0x08, 0x0b, 0x64, 0xea, 0x43, 0x51, 0x5e, 0xa6, 0xcf, 0xce, 0xb7, 0xf3, 0x91, 0xc9, - 0x7e, 0x8a, 0xda, 0xbe, 0xec, 0x3f, 0x67, 0x60, 0x7b, 0xd4, 0x5b, 0x25, 0xda, 0x73, 0x55, 0xef, - 0xde, 0x86, 0xf4, 0x3e, 0x95, 0x75, 0xd4, 0xa6, 0x62, 0x47, 0x50, 0x59, 0x47, 0x6d, 0x8f, 0x4a, - 0xa7, 0x20, 0xc7, 0xa9, 0x5c, 0x98, 0x0b, 0x95, 0x8b, 0x31, 0x54, 0x0a, 0xb0, 0x1f, 0x49, 0x96, - 0x4f, 0xe7, 0x8f, 0x69, 0xc8, 0x07, 0x88, 0x6a, 0x87, 0x18, 0x78, 0xf6, 0x4d, 0xe3, 0xfd, 0xc8, - 0x9c, 0xbe, 0x59, 0xec, 0x43, 0x31, 0x22, 0x37, 0x3f, 0xf7, 0x37, 0x19, 0xd8, 0x19, 0xf3, 0xdf, - 0x62, 0x2d, 0x8c, 0x36, 0xd4, 0xec, 0x7b, 0x36, 0xd4, 0xdb, 0x2d, 0x87, 0x03, 0x28, 0x45, 0x13, - 0xe6, 0x73, 0xfa, 0x2a, 0x03, 0xff, 0x3b, 0x37, 0x14, 0x19, 0xa3, 0xc1, 0xd7, 0x75, 0xd4, 0xc6, - 0x26, 0xf7, 0x04, 0x72, 0x3d, 0xfa, 0x44, 0x99, 0x5c, 0x3d, 0x2e, 0x46, 0xee, 0x64, 0x2e, 0x98, - 0x6d, 0x64, 0x6c, 0x00, 0xf7, 0x39, 0x6c, 0xb8, 0xe9, 0x22, 0xd2, 0xed, 0xaa, 0x66, 0x17, 0x6b, - 0x26, 0xa5, 0x77, 0xad, 0x52, 0xb4, 0x2d, 0x61, 0x37, 0xbc, 0xa0, 0x00, 0x21, 0xca, 0xeb, 0xd4, - 0x54, 0xf5, 0x2d, 0x13, 0xa4, 0x65, 0xe7, 0x42, 0xda, 0x42, 0x0c, 0x69, 0xbb, 0xb4, 0xe1, 0x04, - 0x8c, 0xf8, 0x5c, 0xfd, 0x91, 0x01, 0x38, 0x37, 0x94, 0x4b, 0xb5, 0x8b, 0x49, 0xff, 0xdf, 0x21, - 0xaa, 0xaf, 0xe9, 0x18, 0x61, 0x75, 0x80, 0x9b, 0x71, 0x44, 0x05, 0x08, 0x8f, 0xa8, 0x6f, 0x7c, - 0xcb, 0x5c, 0x89, 0xfa, 0x12, 0x38, 0x0d, 0xbf, 0x34, 0x6b, 0x06, 0xfe, 0xbe, 0x8f, 0x35, 0x84, - 0x6b, 0x3a, 0x46, 0x03, 0x4a, 0xda, 0x42, 0x65, 0xdf, 0xb6, 0x84, 0xbb, 0x6e, 0x84, 0x49, 0x8c, - 0x28, 0x6f, 0x38, 0xc6, 0x0b, 0x66, 0x73, 0x88, 0x4c, 0x50, 0xaa, 0x5b, 0xf4, 0x2c, 0xcb, 0xb8, - 0x0d, 0xda, 0x95, 0xbb, 0xe9, 0x33, 0xf3, 0x33, 0x8d, 0xd6, 0xf0, 0xc7, 0xc0, 0xfc, 0xa7, 0xb0, - 0xca, 0x0a, 0xd9, 0xc9, 0x88, 0xb5, 0x83, 0x1d, 0xdb, 0x12, 0xb8, 0x91, 0x2a, 0x77, 0x9c, 0xa2, - 0xec, 0x36, 0x0e, 0x37, 0xf7, 0x79, 0x36, 0x84, 0x68, 0xc9, 0x16, 0x3f, 0x54, 0xb2, 0xdc, 0x3f, - 0xee, 0xdb, 0xa3, 0xda, 0xf8, 0xca, 0xfd, 0x92, 0xa1, 0x82, 0x9e, 0xa2, 0xb6, 0x46, 0x5e, 0x74, - 0x70, 0x53, 0xc1, 0xf4, 0xd3, 0xfe, 0x00, 0xe9, 0x0e, 0x61, 0xbd, 0x3e, 0x1a, 0xcd, 0x55, 0x4e, - 0x1e, 0x37, 0x07, 0xe2, 0x38, 0x03, 0x9b, 0x71, 0xe2, 0x50, 0xa7, 0x27, 0xce, 0xa9, 0xf3, 0xf2, - 0x1f, 0x77, 0xeb, 0x3d, 0x7a, 0x57, 0x1a, 0x63, 0xcc, 0x23, 0xf4, 0xf8, 0xcd, 0x32, 0x64, 0xcf, - 0x0d, 0x85, 0x6b, 0xc3, 0xfa, 0xf8, 0x8d, 0xef, 0x7e, 0x24, 0x89, 0x93, 0xf7, 0x2e, 0x5e, 0x4a, - 0x08, 0xf4, 0x2f, 0x68, 0x2d, 0xb8, 0x33, 0x76, 0xcd, 0xba, 0x97, 0x20, 0xc4, 0xa5, 0x3e, 0xe4, - 0xcb, 0xc9, 0x70, 0x31, 0x33, 0x39, 0x27, 0xa9, 0x24, 0x33, 0x9d, 0xa2, 0x76, 0xa2, 0x99, 0x42, - 0x27, 0x4a, 0xce, 0x04, 0x2e, 0xe2, 0x34, 0xf9, 0x20, 0x41, 0x14, 0x86, 0xe5, 0x8f, 0x93, 0x63, - 0xfd, 0x59, 0x35, 0xd8, 0x98, 0x38, 0x74, 0x1d, 0x4e, 0x89, 0xe3, 0x23, 0xf9, 0x47, 0x49, 0x91, - 0xfe, 0x7c, 0x2f, 0x20, 0x1f, 0x79, 0x50, 0x4a, 0x12, 0xc8, 0x5b, 0xe7, 0xc9, 0x0c, 0x60, 0x7f, - 0xe2, 0xef, 0x00, 0x42, 0xa7, 0x09, 0x31, 0x2e, 0x44, 0x80, 0xe1, 0x1f, 0x4c, 0xc7, 0xf8, 0xd1, - 0x2f, 0x60, 0xc9, 0xdb, 0x7f, 0x85, 0xb8, 0x61, 0x0c, 0xc0, 0xdf, 0x9f, 0x02, 0x08, 0xd7, 0xde, - 0xd8, 0x0e, 0x73, 0x6f, 0xca, 0x50, 0x86, 0x8b, 0xaf, 0xbd, 0xe8, 0xae, 0xe8, 0x7c, 0xbc, 0xe3, - 0x1d, 0x31, 0x36, 0xcb, 0x31, 0x60, 0xfc, 0xc7, 0x1b, 0xd3, 0x31, 0x2a, 0x17, 0x6f, 0xaf, 0x4b, - 0xe9, 0x77, 0xd7, 0xa5, 0xf4, 0x9f, 0xd7, 0xa5, 0xf4, 0xab, 0x9b, 0x52, 0xea, 0xdd, 0x4d, 0x29, - 0xf5, 0xfb, 0x4d, 0x29, 0x75, 0xf5, 0x44, 0x51, 0xcd, 0x56, 0xbf, 0x51, 0x46, 0xa4, 0x2b, 0x21, - 0x62, 0x74, 0x89, 0x21, 0xa9, 0x0d, 0xf4, 0x50, 0x21, 0xd2, 0xe0, 0x44, 0xea, 0x92, 0x66, 0xbf, - 0x83, 0x0d, 0xf7, 0xe7, 0xd3, 0xa3, 0xc7, 0x0f, 0xbd, 0xff, 0x4f, 0xe6, 0xb0, 0x87, 0x8d, 0x46, - 0x8e, 0xfe, 0x7b, 0x3a, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x64, 0xa7, 0xfd, 0x0a, 0x13, - 0x00, 0x00, + // 1267 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4b, 0x6f, 0xdb, 0x46, + 0x10, 0xd6, 0xcb, 0xb2, 0x3d, 0x72, 0x6d, 0x99, 0xf2, 0x43, 0xa1, 0x62, 0x51, 0xe5, 0x21, 0x11, + 0x5c, 0x44, 0xf2, 0x23, 0x40, 0x11, 0xa3, 0x40, 0x61, 0xa9, 0x0a, 0x6a, 0xb4, 0x7e, 0x80, 0xb2, + 0x7b, 0x70, 0x8b, 0x0a, 0x12, 0xb5, 0x91, 0x09, 0x49, 0x5c, 0x95, 0xa4, 0x94, 0xe8, 0x1f, 0x04, + 0x3e, 0xe5, 0x6c, 0xc0, 0x40, 0x8a, 0x1e, 0x7b, 0x48, 0x7f, 0x46, 0x8e, 0x39, 0xb5, 0x45, 0x0f, + 0x42, 0x61, 0x5f, 0x7a, 0xd6, 0x2f, 0x28, 0xb8, 0x5c, 0x52, 0x94, 0x44, 0xc2, 0x74, 0x62, 0x3b, + 0xb9, 0xed, 0xce, 0x7c, 0x3b, 0x3b, 0xfb, 0x7d, 0xc3, 0x7d, 0x10, 0xee, 0x4b, 0x15, 0x31, 0x2b, + 0x62, 0x05, 0x65, 0xc5, 0x93, 0xb2, 0x2c, 0xa3, 0x46, 0xb6, 0xb3, 0x9e, 0xd5, 0x5e, 0x64, 0x5a, + 0x0a, 0xd6, 0x30, 0x13, 0x93, 0x2a, 0x62, 0x46, 0xf7, 0x66, 0xa8, 0x37, 0xd3, 0x59, 0x67, 0x17, + 0x6a, 0xb8, 0x86, 0x89, 0x3f, 0xab, 0xb7, 0x0c, 0x28, 0xcb, 0x0d, 0x02, 0x35, 0x24, 0x24, 0x6b, + 0x7a, 0x1c, 0xa3, 0x45, 0x01, 0x9f, 0x3b, 0xcd, 0x64, 0x86, 0x25, 0x10, 0xfe, 0x57, 0x3f, 0x30, + 0xbb, 0x6a, 0x2d, 0x6f, 0x18, 0xf7, 0x5b, 0x48, 0xde, 0x91, 0x25, 0x8d, 0xf9, 0x02, 0x26, 0x5b, + 0x58, 0xd1, 0x4a, 0x52, 0x35, 0xee, 0x4f, 0xf9, 0xd3, 0xd3, 0x39, 0xa6, 0xdf, 0xe3, 0x66, 0xbb, + 0xe5, 0x66, 0x63, 0x8b, 0xa7, 0x0e, 0x5e, 0x08, 0xeb, 0xad, 0x9d, 0x2a, 0xf3, 0x15, 0x4c, 0xd2, + 0xa0, 0xf1, 0x40, 0xca, 0x9f, 0x8e, 0x6c, 0xdc, 0xcf, 0x38, 0x2c, 0x22, 0x43, 0xe7, 0xc8, 0x85, + 0xde, 0xf6, 0x38, 0x9f, 0x60, 0x0e, 0x61, 0x96, 0x20, 0xac, 0x4a, 0x35, 0x19, 0x29, 0xf1, 0xa0, + 0x3e, 0x93, 0x40, 0x7b, 0x5b, 0x53, 0x2f, 0x5f, 0x73, 0xbe, 0xff, 0x5e, 0x73, 0x3e, 0x5e, 0x00, + 0x76, 0x3c, 0x45, 0x01, 0xa9, 0x2d, 0x2c, 0xab, 0x88, 0x79, 0x0c, 0x40, 0x43, 0x0d, 0xb2, 0x5d, + 0xec, 0xf7, 0xb8, 0x79, 0x23, 0xdb, 0x81, 0x8f, 0x17, 0xa6, 0x69, 0x67, 0xa7, 0xca, 0xff, 0x19, + 0x84, 0xf9, 0xe1, 0xa0, 0x87, 0x4a, 0xf7, 0x7a, 0xcb, 0xde, 0x83, 0x58, 0x4b, 0x41, 0x1d, 0x09, + 0xb7, 0xd5, 0x92, 0x2d, 0x83, 0x00, 0x19, 0x98, 0xec, 0xf7, 0x38, 0x96, 0x0e, 0x1c, 0x07, 0xf1, + 0xc2, 0xbc, 0x69, 0xcd, 0x9b, 0x29, 0xd9, 0x69, 0x0c, 0x5e, 0x9f, 0x46, 0x01, 0x16, 0x44, 0xdc, + 0x96, 0x35, 0xa4, 0xb4, 0xca, 0x8a, 0xd6, 0x2d, 0x75, 0x90, 0xa2, 0x4a, 0x58, 0x8e, 0x87, 0x48, + 0x3a, 0x5c, 0xbf, 0xc7, 0x25, 0x28, 0x21, 0x0e, 0x28, 0x5e, 0x88, 0xd9, 0xcd, 0x3f, 0x18, 0x56, + 0x9d, 0xda, 0x96, 0x82, 0xf1, 0xb3, 0x92, 0x24, 0x4b, 0x5a, 0x7c, 0x22, 0xe5, 0x4f, 0xcf, 0xd8, + 0xa9, 0x1d, 0xf8, 0x78, 0x61, 0x9a, 0x74, 0x48, 0xed, 0x1c, 0xc3, 0x8c, 0xe1, 0x39, 0x41, 0x52, + 0xed, 0x44, 0x8b, 0x87, 0xc9, 0x62, 0x58, 0xdb, 0x62, 0x8c, 0x1a, 0xed, 0xac, 0x67, 0xbe, 0x25, + 0x88, 0x5c, 0x42, 0x5f, 0x4a, 0xbf, 0xc7, 0xc5, 0xec, 0x71, 0x8d, 0xd1, 0xbc, 0x10, 0x21, 0x5d, + 0x03, 0x69, 0x2b, 0x96, 0x49, 0x97, 0x62, 0x49, 0xc0, 0xbd, 0x31, 0x5d, 0xcd, 0x5a, 0xe1, 0xff, + 0x1a, 0x53, 0x7d, 0x5b, 0xac, 0x5f, 0x4f, 0xf5, 0xe1, 0x72, 0x0b, 0x78, 0x2b, 0x37, 0xe6, 0x18, + 0x96, 0x87, 0x78, 0xb7, 0x85, 0x20, 0x55, 0x9f, 0xe3, 0xfb, 0x3d, 0x2e, 0xe9, 0x20, 0x90, 0x3d, + 0xde, 0xa2, 0xdd, 0x33, 0xa8, 0x9b, 0xdb, 0x50, 0x7e, 0x1d, 0x0c, 0x41, 0x4b, 0x9a, 0xd2, 0xa5, + 0xc2, 0x2f, 0xf4, 0x7b, 0x5c, 0xd4, 0x2e, 0x90, 0xa6, 0x74, 0x79, 0x61, 0x8a, 0xb4, 0xf5, 0x6f, + 0xe7, 0x13, 0x93, 0x7d, 0x5b, 0xac, 0x5b, 0xb2, 0xff, 0x1e, 0x80, 0xc5, 0x61, 0x6f, 0x1e, 0xcb, + 0xcf, 0x24, 0xa5, 0x79, 0x17, 0xd2, 0x5b, 0x54, 0x96, 0xc5, 0x3a, 0x11, 0xdb, 0x81, 0xca, 0xb2, + 0x58, 0x37, 0xa9, 0xd4, 0x0b, 0x72, 0x94, 0xca, 0xd0, 0xad, 0x50, 0x39, 0xe1, 0x42, 0x25, 0x07, + 0x2b, 0x8e, 0x64, 0x59, 0x74, 0x9e, 0xf9, 0x21, 0x36, 0x40, 0xe4, 0x1b, 0x58, 0x45, 0xd7, 0x3f, + 0x34, 0xde, 0x8f, 0xcc, 0xab, 0x0f, 0x8b, 0x15, 0x48, 0x38, 0xe4, 0x66, 0xe5, 0xfe, 0x26, 0x00, + 0x4b, 0x23, 0xfe, 0x3b, 0xac, 0x85, 0xe1, 0x0d, 0x35, 0xf8, 0x9e, 0x1b, 0xea, 0xdd, 0x96, 0x43, + 0x0a, 0x92, 0xce, 0x84, 0x59, 0x9c, 0xbe, 0x0a, 0xc0, 0x67, 0xbb, 0x6a, 0x4d, 0x40, 0x62, 0xe7, + 0xa0, 0x2c, 0xd6, 0x91, 0xc6, 0x3c, 0x81, 0x70, 0x8b, 0xb4, 0x08, 0x93, 0x91, 0x8d, 0x84, 0xe3, + 0x49, 0x66, 0x80, 0xe9, 0x41, 0x46, 0x07, 0x30, 0x4f, 0x21, 0x6a, 0xa4, 0x2b, 0xe2, 0x66, 0x53, + 0xd2, 0x9a, 0x48, 0xd6, 0x08, 0xbd, 0x33, 0xb9, 0x44, 0xbf, 0xc7, 0x2d, 0xdb, 0x17, 0x34, 0x40, + 0xf0, 0xc2, 0x1c, 0x31, 0xe5, 0x2d, 0xcb, 0x18, 0x69, 0xc1, 0x5b, 0x21, 0x2d, 0xe4, 0x42, 0xda, + 0xcf, 0x64, 0xc3, 0x19, 0x30, 0x62, 0xdd, 0x56, 0xbe, 0x86, 0xb0, 0x82, 0xd4, 0x76, 0xc3, 0x60, + 0x66, 0x76, 0xe3, 0xa1, 0x23, 0x33, 0x26, 0x5c, 0x20, 0xd0, 0xc3, 0x6e, 0x0b, 0x09, 0x74, 0xd8, + 0x56, 0x48, 0x9f, 0x83, 0xff, 0x27, 0x00, 0xb0, 0xab, 0xd6, 0x0e, 0xa5, 0x26, 0xc2, 0xed, 0x9b, + 0xe1, 0xbb, 0x2d, 0x2b, 0x48, 0x44, 0x52, 0x07, 0x55, 0xdd, 0xf8, 0x1e, 0x20, 0x4c, 0xbe, 0x8f, + 0x2c, 0xcb, 0xad, 0xf2, 0xfd, 0x1d, 0x30, 0x32, 0x7a, 0xa1, 0x95, 0x54, 0xf4, 0x4b, 0x1b, 0xc9, + 0x22, 0x2a, 0x29, 0x48, 0xec, 0x10, 0xee, 0x43, 0xb9, 0x95, 0x7e, 0x8f, 0xbb, 0x67, 0x44, 0x18, + 0xc7, 0xf0, 0x42, 0x54, 0x37, 0x16, 0xa9, 0x4d, 0xd7, 0xc3, 0x43, 0xc5, 0xff, 0x48, 0xae, 0xc4, + 0x94, 0xdb, 0x9b, 0x56, 0xee, 0xcc, 0xb8, 0x82, 0xd0, 0xe8, 0xfb, 0x32, 0xf9, 0xa2, 0x3e, 0x05, + 0x01, 0xbf, 0x84, 0x08, 0xfd, 0xac, 0xf4, 0x8c, 0xe8, 0xe6, 0xb4, 0xd4, 0xef, 0x71, 0xcc, 0xd0, + 0x37, 0xa7, 0x3b, 0x79, 0xc1, 0xd8, 0xc6, 0x8c, 0xdc, 0x6f, 0x73, 0x7b, 0x72, 0x56, 0x7e, 0xe2, + 0x43, 0x95, 0x0f, 0xbb, 0x28, 0x5f, 0x21, 0xb7, 0x88, 0x61, 0x6d, 0x6e, 0xba, 0x00, 0xfe, 0x08, + 0x90, 0xf2, 0xda, 0x16, 0xeb, 0x32, 0x7e, 0xde, 0x40, 0xd5, 0x1a, 0x22, 0xfb, 0xd5, 0x07, 0x54, + 0x40, 0x1a, 0xe6, 0xca, 0xc3, 0xd1, 0x8c, 0x02, 0x10, 0x46, 0xcd, 0x03, 0x8d, 0xf5, 0x81, 0x55, + 0x37, 0x8d, 0x89, 0xd3, 0xd4, 0x78, 0x5b, 0xef, 0x7c, 0xe4, 0x23, 0x48, 0x24, 0x0f, 0xc0, 0x11, + 0xc6, 0x6e, 0x58, 0x97, 0xd5, 0x33, 0x3f, 0x30, 0xe3, 0x20, 0x66, 0x0d, 0x12, 0x42, 0xa1, 0x78, + 0xb0, 0xbf, 0x57, 0x2c, 0x94, 0x84, 0x42, 0xf1, 0xe8, 0xfb, 0xc3, 0xd2, 0xd1, 0x5e, 0xf1, 0xa0, + 0x90, 0xdf, 0x79, 0xba, 0x53, 0xf8, 0x26, 0xea, 0x63, 0xe7, 0x4e, 0xcf, 0x53, 0x11, 0x9b, 0x89, + 0xe1, 0x61, 0x61, 0x74, 0xc4, 0xde, 0xfe, 0xfe, 0x41, 0xd4, 0xcf, 0x4e, 0x9d, 0x9e, 0xa7, 0x42, + 0x7a, 0x9b, 0x49, 0xc3, 0xf2, 0x28, 0xa6, 0x78, 0x94, 0xcf, 0x17, 0x8a, 0xc5, 0x68, 0x80, 0x8d, + 0x9c, 0x9e, 0xa7, 0x26, 0x69, 0x97, 0x0d, 0xbd, 0xfc, 0x2d, 0xe9, 0xdb, 0x78, 0x33, 0x05, 0xc1, + 0x5d, 0xb5, 0xc6, 0xd4, 0x61, 0x6e, 0xf4, 0xa9, 0xee, 0xbc, 0xdc, 0xf1, 0x07, 0x33, 0x9b, 0xf5, + 0x08, 0xb4, 0x88, 0x3d, 0x81, 0xd9, 0x91, 0xf7, 0xf1, 0x03, 0x0f, 0x21, 0x0e, 0x95, 0x2e, 0x9b, + 0xf1, 0x86, 0x73, 0x99, 0x49, 0xbf, 0x02, 0x7b, 0x99, 0x69, 0x5b, 0xac, 0x7b, 0x9a, 0xc9, 0xf6, + 0x14, 0x60, 0x34, 0x60, 0x1c, 0x9e, 0x01, 0xab, 0x1e, 0xa2, 0x50, 0x2c, 0xbb, 0xe1, 0x1d, 0x6b, + 0xcd, 0x2a, 0x43, 0x74, 0xec, 0xb6, 0x9c, 0xbe, 0x22, 0x8e, 0x85, 0x64, 0xd7, 0xbc, 0x22, 0xad, + 0xf9, 0x9e, 0x43, 0xcc, 0xf1, 0x86, 0xeb, 0x25, 0x90, 0xb9, 0xce, 0xcd, 0x6b, 0x80, 0xad, 0x89, + 0x7f, 0x02, 0xb0, 0x5d, 0x03, 0x79, 0xb7, 0x10, 0x03, 0x0c, 0xbb, 0x7a, 0x35, 0xc6, 0x8a, 0x5e, + 0x84, 0x49, 0xf3, 0xc6, 0xc3, 0xb9, 0x0d, 0xa3, 0x00, 0xf6, 0xe1, 0x15, 0x00, 0x7b, 0xed, 0x8d, + 0x1c, 0xc6, 0x0f, 0xae, 0x18, 0x4a, 0x71, 0xee, 0xb5, 0xe7, 0x72, 0x80, 0xd4, 0x61, 0x6e, 0x74, + 0xd7, 0x77, 0xcd, 0x72, 0x04, 0xe8, 0xfe, 0xf1, 0xba, 0xec, 0x8a, 0xb9, 0xe2, 0xdb, 0x8b, 0xa4, + 0xff, 0xdd, 0x45, 0xd2, 0xff, 0xef, 0x45, 0xd2, 0xff, 0xea, 0x32, 0xe9, 0x7b, 0x77, 0x99, 0xf4, + 0xfd, 0x7d, 0x99, 0xf4, 0x1d, 0x3f, 0xa9, 0x49, 0xda, 0x49, 0xbb, 0x92, 0x11, 0x71, 0x33, 0x2b, + 0x62, 0xb5, 0x89, 0xd5, 0xac, 0x54, 0x11, 0x1f, 0xd5, 0x70, 0xb6, 0xb3, 0x99, 0x6d, 0xe2, 0x6a, + 0xbb, 0x81, 0x54, 0xe3, 0xaf, 0xe1, 0xda, 0xe3, 0x47, 0xe6, 0x8f, 0x43, 0xad, 0xdb, 0x42, 0x6a, + 0x25, 0x4c, 0x7e, 0x1a, 0x6e, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x99, 0xe1, 0x0c, 0xc3, + 0x14, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1954,6 +1999,11 @@ func (m *MsgRecvPacketResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -2039,6 +2089,11 @@ func (m *MsgTimeoutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -2131,6 +2186,11 @@ func (m *MsgTimeoutOnCloseResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -2218,6 +2278,11 @@ func (m *MsgAcknowledgementResponse) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -2479,6 +2544,9 @@ func (m *MsgRecvPacketResponse) Size() (n int) { } var l int _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } return n } @@ -2512,6 +2580,9 @@ func (m *MsgTimeoutResponse) Size() (n int) { } var l int _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } return n } @@ -2549,6 +2620,9 @@ func (m *MsgTimeoutOnCloseResponse) Size() (n int) { } var l int _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } return n } @@ -2583,6 +2657,9 @@ func (m *MsgAcknowledgementResponse) Size() (n int) { } var l int _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } return n } @@ -4409,6 +4486,25 @@ func (m *MsgRecvPacketResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgRecvPacketResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4660,6 +4756,25 @@ func (m *MsgTimeoutResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgTimeoutResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4945,6 +5060,25 @@ func (m *MsgTimeoutOnCloseResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgTimeoutOnCloseResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -5211,6 +5345,25 @@ func (m *MsgAcknowledgementResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgAcknowledgementResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/modules/core/ante/ante.go b/modules/core/ante/ante.go index 42e392905ec..e9218ea4b94 100644 --- a/modules/core/ante/ante.go +++ b/modules/core/ante/ante.go @@ -4,22 +4,23 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v3/modules/core/keeper" ) type AnteDecorator struct { - k channelkeeper.Keeper + k *keeper.Keeper } -func NewAnteDecorator(k channelkeeper.Keeper) AnteDecorator { +func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { return AnteDecorator{k: k} } -// AnteDecorator returns an error if a multiMsg tx only contains packet messages (Recv, Ack, Timeout) and additional update messages and all packet messages -// are redundant. If the transaction is just a single UpdateClient message, or the multimsg transaction contains some other message type, then the antedecorator returns no error -// and continues processing to ensure these transactions are included. -// This will ensure that relayers do not waste fees on multiMsg transactions when another relayer has already submitted all packets, by rejecting the tx at the mempool layer. +// AnteDecorator returns an error if a multiMsg tx only contains packet messages (Recv, Ack, Timeout) and additional update messages +// and all packet messages are redundant. If the transaction is just a single UpdateClient message, or the multimsg transaction +// contains some other message type, then the antedecorator returns no error and continues processing to ensure these transactions +// are included. This will ensure that relayers do not waste fees on multiMsg transactions when another relayer has already submitted +// all packets, by rejecting the tx at the mempool layer. func (ad AnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { // do not run redundancy check on DeliverTx or simulate if (ctx.IsCheckTx() || ctx.IsReCheckTx()) && !simulate { @@ -29,31 +30,50 @@ func (ad AnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne for _, m := range tx.GetMsgs() { switch msg := m.(type) { case *channeltypes.MsgRecvPacket: - if _, found := ad.k.GetPacketReceipt(ctx, msg.Packet.GetDestPort(), msg.Packet.GetDestChannel(), msg.Packet.GetSequence()); found { + response, err := ad.k.RecvPacket(sdk.WrapSDKContext(ctx), msg) + if err != nil { + return ctx, err + } + if response.Result == channeltypes.NOOP { redundancies += 1 } packetMsgs += 1 case *channeltypes.MsgAcknowledgement: - if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + response, err := ad.k.Acknowledgement(sdk.WrapSDKContext(ctx), msg) + if err != nil { + return ctx, err + } + if response.Result == channeltypes.NOOP { redundancies += 1 } packetMsgs += 1 case *channeltypes.MsgTimeout: - if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + response, err := ad.k.Timeout(sdk.WrapSDKContext(ctx), msg) + if err != nil { + return ctx, err + } + if response.Result == channeltypes.NOOP { redundancies += 1 } packetMsgs += 1 case *channeltypes.MsgTimeoutOnClose: - if commitment := ad.k.GetPacketCommitment(ctx, msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), msg.Packet.GetSequence()); len(commitment) == 0 { + response, err := ad.k.TimeoutOnClose(sdk.WrapSDKContext(ctx), msg) + if err != nil { + return ctx, err + } + if response.Result == channeltypes.NOOP { redundancies += 1 } packetMsgs += 1 case *clienttypes.MsgUpdateClient: - // do nothing here, as we want to avoid updating clients if it is batched with only redundant messages + _, err := ad.k.UpdateClient(sdk.WrapSDKContext(ctx), msg) + if err != nil { + return ctx, err + } default: // if the multiMsg tx has a msg that is not a packet msg or update msg, then we will not return error @@ -61,7 +81,6 @@ func (ad AnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // even if they get batched with redundant packet messages. return next(ctx, tx, simulate) } - } // only return error if all packet messages are redundant diff --git a/modules/core/ante/ante_test.go b/modules/core/ante/ante_test.go index 0336e07a3ae..c04f6483f74 100644 --- a/modules/core/ante/ante_test.go +++ b/modules/core/ante/ante_test.go @@ -4,13 +4,15 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v3/modules/core/24-host" "github.com/cosmos/ibc-go/v3/modules/core/ante" + "github.com/cosmos/ibc-go/v3/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v3/testing" - "github.com/cosmos/ibc-go/v3/testing/mock" ) type AnteTestSuite struct { @@ -42,6 +44,133 @@ func TestAnteTestSuite(t *testing.T) { suite.Run(t, new(AnteTestSuite)) } +// createRecvPacketMessage creates a RecvPacket message for a packet sent from chain A to chain B. +func (suite *AnteTestSuite) createRecvPacketMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + clienttypes.NewHeight(1, 0), 0) + + err := suite.path.EndpointA.SendPacket(packet) + suite.Require().NoError(err) + + if isRedundant { + err = suite.path.EndpointB.RecvPacket(packet) + suite.Require().NoError(err) + } + + err = suite.path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + proof, proofHeight := suite.chainA.QueryProof(packetKey) + + return channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) +} + +// createAcknowledgementMessage creates an Acknowledgement message for a packet sent from chain B to chain A. +func (suite *AnteTestSuite) createAcknowledgementMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + clienttypes.NewHeight(1, 0), 0) + + err := suite.path.EndpointB.SendPacket(packet) + suite.Require().NoError(err) + err = suite.path.EndpointA.RecvPacket(packet) + suite.Require().NoError(err) + + if isRedundant { + err = suite.path.EndpointB.AcknowledgePacket(packet, ibctesting.MockAcknowledgement) + suite.Require().NoError(err) + } + + packetKey := host.PacketAcknowledgementKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + proof, proofHeight := suite.chainA.QueryProof(packetKey) + + return channeltypes.NewMsgAcknowledgement(packet, ibctesting.MockAcknowledgement, proof, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) +} + +// createTimeoutMessage creates an Timeout message for a packet sent from chain B to chain A. +func (suite *AnteTestSuite) createTimeoutMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { + height := suite.chainA.LastHeader.GetHeight() + timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + timeoutHeight, 0) + + err := suite.path.EndpointB.SendPacket(packet) + suite.Require().NoError(err) + + suite.coordinator.CommitNBlocks(suite.chainA, 3) + + err = suite.path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + if isRedundant { + err = suite.path.EndpointB.TimeoutPacket(packet) + suite.Require().NoError(err) + } + + packetKey := host.PacketReceiptKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + proof, proofHeight := suite.chainA.QueryProof(packetKey) + + return channeltypes.NewMsgTimeout(packet, sequenceNumber, proof, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) +} + +// createTimeoutOnCloseMessage creates an TimeoutOnClose message for a packet sent from chain B to chain A. +func (suite *AnteTestSuite) createTimeoutOnCloseMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { + height := suite.chainA.LastHeader.GetHeight() + timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + timeoutHeight, 0) + + err := suite.path.EndpointB.SendPacket(packet) + suite.Require().NoError(err) + err = suite.path.EndpointA.SetChannelClosed() + suite.Require().NoError(err) + + if isRedundant { + err = suite.path.EndpointB.TimeoutOnClose(packet) + suite.Require().NoError(err) + } + + packetKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + proof, proofHeight := suite.chainA.QueryProof(packetKey) + + channelKey := host.ChannelKey(packet.GetDestPort(), packet.GetDestChannel()) + proofClosed, _ := suite.chainA.QueryProof(channelKey) + + return channeltypes.NewMsgTimeoutOnClose(packet, 1, proof, proofClosed, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) +} + +func (suite *AnteTestSuite) createUpdateClientMessage() sdk.Msg { + endpoint := suite.path.EndpointB + + // ensure counterparty has committed state + endpoint.Chain.Coordinator.CommitBlock(endpoint.Counterparty.Chain) + + var header exported.Header + + switch endpoint.ClientConfig.GetClientType() { + case exported.Tendermint: + header, _ = endpoint.Chain.ConstructUpdateTMClientHeader(endpoint.Counterparty.Chain, endpoint.ClientID) + + default: + } + + msg, err := clienttypes.NewMsgUpdateClient( + endpoint.ClientID, header, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + require.NoError(endpoint.Chain.T, err) + + return msg +} + func (suite *AnteTestSuite) TestAnteDecorator() { testCases := []struct { name string @@ -49,404 +178,276 @@ func (suite *AnteTestSuite) TestAnteDecorator() { expPass bool }{ { - "success on single msg", + "success on one new RecvPacket message", func(suite *AnteTestSuite) []sdk.Msg { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), 1, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - return []sdk.Msg{channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")} + // the RecvPacket message has not been submitted to the chain yet, so it will succeed + return []sdk.Msg{suite.createRecvPacketMessage(1, false)} }, true, }, { - "success on multiple msgs", + "success on one new Acknowledgement message", func(suite *AnteTestSuite) []sdk.Msg { - var msgs []sdk.Msg - - for i := 1; i <= 5; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - return msgs + // the Acknowledgement message has not been submitted to the chain yet, so it will succeed + return []sdk.Msg{suite.createAcknowledgementMessage(1, false)} }, true, }, { - "success on multiple msgs: 1 fresh recv packet", + "success on one new Timeout message", func(suite *AnteTestSuite) []sdk.Msg { - var msgs []sdk.Msg - - for i := 1; i <= 5; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - err := suite.path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - // receive all sequences except packet 3 - if i != 3 { - err = suite.path.EndpointB.RecvPacket(packet) - suite.Require().NoError(err) - } - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - - return msgs + // the Timeout message has not been submitted to the chain yet, so it will succeed + return []sdk.Msg{suite.createTimeoutMessage(1, false)} }, true, }, { - "success on multiple mixed msgs", + "success on one new TimeoutOnClose message", + func(suite *AnteTestSuite) []sdk.Msg { + // the TimeoutOnClose message has not been submitted to the chain yet, so it will succeed + return []sdk.Msg{suite.createTimeoutOnCloseMessage(uint64(1), false)} + }, + true, + }, + { + "success on three new messages of each type", func(suite *AnteTestSuite) []sdk.Msg { var msgs []sdk.Msg + // none of the messages of each type has been submitted to the chain yet, + // the first message is succeed and the next two of each type will be rejected + // because they are redundant. + + // from A to B for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - err := suite.path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), false)) } - for i := 4; i <= 6; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - msgs = append(msgs, channeltypes.NewMsgTimeout(packet, uint64(i), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + + // from B to A + for i := 1; i <= 9; i++ { + switch { + case i >= 1 && i <= 3: + msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), false)) + case i >= 4 && i <= 6: + msgs = append(msgs, suite.createTimeoutMessage(uint64(i), false)) + case i >= 7 && i <= 9: + msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), false)) + } } return msgs }, true, }, { - "success on multiple mixed msgs: 1 fresh packet of each type", + "success on three redundant messages of RecvPacket, Acknowledgement and TimeoutOnClose, and one new Timeout message", func(suite *AnteTestSuite) []sdk.Msg { var msgs []sdk.Msg - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - err := suite.path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - // receive all sequences except packet 3 - if i != 3 { - - err := suite.path.EndpointB.RecvPacket(packet) - suite.Require().NoError(err) - } + // we pass three messages of RecvPacket, Acknowledgement and TimeoutOnClose that + // are all redundant (i.e. those messages have already been submitted and + // processed by the chain). But these messages will not be rejected because the + // Timeout message is new. - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } + // from A to B for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - // receive all acks except ack 2 - if i != 2 { - err = suite.path.EndpointA.RecvPacket(packet) - suite.Require().NoError(err) - err = suite.path.EndpointB.AcknowledgePacket(packet, mock.MockAcknowledgement.Acknowledgement()) - suite.Require().NoError(err) - } - - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) } - for i := 4; i <= 6; i++ { - height := suite.chainA.LastHeader.GetHeight() - timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - // timeout packet - suite.coordinator.CommitNBlocks(suite.chainA, 3) - - // timeout packets except sequence 5 - if i != 5 { - suite.path.EndpointB.UpdateClient() - err = suite.path.EndpointB.TimeoutPacket(packet) - suite.Require().NoError(err) - } - msgs = append(msgs, channeltypes.NewMsgTimeout(packet, uint64(i), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + // from B to A + for i := 1; i <= 7; i++ { + switch { + case i >= 1 && i <= 3: + msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + case i == 4: + msgs = append(msgs, suite.createTimeoutMessage(uint64(i), false)) + case i >= 5 && i <= 7: + msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + } } return msgs }, true, }, { - "success on multiple mixed msgs: only 1 fresh msg in total", + "success on one new message and two redundant messages of each type", func(suite *AnteTestSuite) []sdk.Msg { var msgs []sdk.Msg - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all packets - suite.path.EndpointA.SendPacket(packet) - suite.path.EndpointB.RecvPacket(packet) + // For each type there is a new message and two messages that are redundant + // (i.e. they have been already submitted and processed by the chain). But all + // the redundant messages will not be rejected because there is a new message + // of each type. - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } + // from A to B for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all acks - suite.path.EndpointB.SendPacket(packet) - suite.path.EndpointA.RecvPacket(packet) - suite.path.EndpointB.AcknowledgePacket(packet, mock.MockAcknowledgement.Acknowledgement()) - - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), i != 2)) } - for i := 4; i < 5; i++ { - height := suite.chainA.LastHeader.GetHeight() - timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - - // do not timeout packet, timeout msg is fresh - suite.path.EndpointB.SendPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgTimeout(packet, uint64(i), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + + // from B to A + for i := 1; i <= 9; i++ { + switch { + case i >= 1 && i <= 3: + msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), i != 2)) + case i >= 4 && i <= 6: + msgs = append(msgs, suite.createTimeoutMessage(uint64(i), i != 5)) + case i >= 7 && i <= 9: + msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), i != 8)) + } } return msgs }, true, }, { - "success on single update client msg", + "success on one new UpdateClient message", func(suite *AnteTestSuite) []sdk.Msg { - return []sdk.Msg{&clienttypes.MsgUpdateClient{}} + return []sdk.Msg{suite.createUpdateClientMessage()} }, true, }, { - "success on multiple update clients", + "success on three new UpdateClient messages", func(suite *AnteTestSuite) []sdk.Msg { - return []sdk.Msg{&clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}} + return []sdk.Msg{suite.createUpdateClientMessage(), suite.createUpdateClientMessage(), suite.createUpdateClientMessage()} }, true, }, { - "success on multiple update clients and fresh packet message", + "success on three new Updateclient messages and one new RecvPacket message", func(suite *AnteTestSuite) []sdk.Msg { - msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}} - - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), 1, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - return append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + return []sdk.Msg{ + suite.createUpdateClientMessage(), + suite.createUpdateClientMessage(), + suite.createUpdateClientMessage(), + suite.createRecvPacketMessage(uint64(1), false), + } }, true, }, { - "success of tx with different msg type even if all packet messages are redundant", + "success on three redundant RecvPacket messages and one SubmitMisbehaviour message", func(suite *AnteTestSuite) []sdk.Msg { - msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{}} + msgs := []sdk.Msg{suite.createUpdateClientMessage()} for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all packets - suite.path.EndpointA.SendPacket(packet) - suite.path.EndpointB.RecvPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all acks - suite.path.EndpointB.SendPacket(packet) - suite.path.EndpointA.RecvPacket(packet) - suite.path.EndpointB.AcknowledgePacket(packet, mock.MockAcknowledgement.Acknowledgement()) - - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - for i := 4; i < 6; i++ { - height := suite.chainA.LastHeader.GetHeight() - timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - // timeout packet - suite.coordinator.CommitNBlocks(suite.chainA, 3) - - suite.path.EndpointB.UpdateClient() - suite.path.EndpointB.TimeoutPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgTimeoutOnClose(packet, uint64(i), []byte("proof"), []byte("channelProof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) } // append non packet and update message to msgs to ensure multimsg tx should pass msgs = append(msgs, &clienttypes.MsgSubmitMisbehaviour{}) - return msgs }, true, }, { - "no success on multiple mixed message: all are redundant", + "no success on one redundant RecvPacket message", + func(suite *AnteTestSuite) []sdk.Msg { + return []sdk.Msg{suite.createRecvPacketMessage(uint64(1), true)} + }, + false, + }, + { + "no success on three redundant messages of each type", func(suite *AnteTestSuite) []sdk.Msg { var msgs []sdk.Msg + // from A to B for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all packets - suite.path.EndpointA.SendPacket(packet) - suite.path.EndpointB.RecvPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) } - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - // receive all acks - suite.path.EndpointB.SendPacket(packet) - suite.path.EndpointA.RecvPacket(packet) - suite.path.EndpointB.AcknowledgePacket(packet, mock.MockAcknowledgement.Acknowledgement()) - - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) - } - for i := 4; i < 6; i++ { - height := suite.chainA.LastHeader.GetHeight() - timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - // timeout packet - suite.coordinator.CommitNBlocks(suite.chainA, 3) - - suite.path.EndpointB.UpdateClient() - suite.path.EndpointB.TimeoutPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgTimeoutOnClose(packet, uint64(i), []byte("proof"), []byte("channelProof"), clienttypes.NewHeight(0, 1), "signer")) + // from B to A + for i := 1; i <= 9; i++ { + switch { + case i >= 1 && i <= 3: + msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + case i >= 4 && i <= 6: + msgs = append(msgs, suite.createTimeoutMessage(uint64(i), true)) + case i >= 7 && i <= 9: + msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + } } return msgs }, false, }, { - "no success if msgs contain update clients and redundant packet messages", + "no success on one new UpdateClient message and three redundant RecvPacket messages", func(suite *AnteTestSuite) []sdk.Msg { - msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}, &clienttypes.MsgUpdateClient{}} + msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{}} for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - // receive all packets - suite.path.EndpointA.SendPacket(packet) - suite.path.EndpointB.RecvPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) } - for i := 1; i <= 3; i++ { - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - // receive all acks - suite.path.EndpointB.SendPacket(packet) - suite.path.EndpointA.RecvPacket(packet) - suite.path.EndpointB.AcknowledgePacket(packet, mock.MockAcknowledgement.Acknowledgement()) + return msgs + }, + false, + }, + { + "no success on three new UpdateClient messages and three redundant messages of each type", + func(suite *AnteTestSuite) []sdk.Msg { + msgs := []sdk.Msg{suite.createUpdateClientMessage(), suite.createUpdateClientMessage(), suite.createUpdateClientMessage()} - msgs = append(msgs, channeltypes.NewMsgAcknowledgement(packet, []byte("ack"), []byte("proof"), clienttypes.NewHeight(0, 1), "signer")) + // from A to B + for i := 1; i <= 3; i++ { + msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) } - for i := 4; i < 6; i++ { - height := suite.chainA.LastHeader.GetHeight() - timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket([]byte(mock.MockPacketData), uint64(i), - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - // timeout packet - suite.coordinator.CommitNBlocks(suite.chainA, 3) - suite.path.EndpointB.UpdateClient() - suite.path.EndpointB.TimeoutPacket(packet) - - msgs = append(msgs, channeltypes.NewMsgTimeoutOnClose(packet, uint64(i), []byte("proof"), []byte("channelProof"), clienttypes.NewHeight(0, 1), "signer")) + // from B to A + for i := 1; i <= 9; i++ { + switch { + case i >= 1 && i <= 3: + msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + case i >= 4 && i <= 6: + msgs = append(msgs, suite.createTimeoutMessage(uint64(i), true)) + case i >= 7 && i <= 9: + msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + } } return msgs }, false, }, + { + "no success on one new message and one invalid message", + func(suite *AnteTestSuite) []sdk.Msg { + packet := channeltypes.NewPacket(ibctesting.MockPacketData, 2, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + clienttypes.NewHeight(1, 0), 0) + + return []sdk.Msg{ + suite.createRecvPacketMessage(uint64(1), false), + channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer"), + } + }, + false, + }, + { + "no success on one new message and one redundant message in the same block", + func(suite *AnteTestSuite) []sdk.Msg { + msg := suite.createRecvPacketMessage(uint64(1), false) + + // We want to be able to run check tx with the non-redundant message without + // commiting it to a block, so that the when check tx runs with the redundant + // message they are both in the same block + k := suite.chainB.App.GetIBCKeeper() + decorator := ante.NewAnteDecorator(k) + checkCtx := suite.chainB.GetContext().WithIsCheckTx(true) + next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil } + txBuilder := suite.chainB.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs([]sdk.Msg{msg}...) + suite.Require().NoError(err) + tx := txBuilder.GetTx() + + _, err = decorator.AnteHandle(checkCtx, tx, false, next) + suite.Require().NoError(err) + + return []sdk.Msg{msg} + }, + false, + }, } for _, tc := range testCases { @@ -456,7 +457,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // reset suite suite.SetupTest() - k := suite.chainB.App.GetIBCKeeper().ChannelKeeper + k := suite.chainB.App.GetIBCKeeper() decorator := ante.NewAnteDecorator(k) msgs := tc.malleate(suite) diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index a380540614c..be18391c698 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -395,7 +395,7 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke case nil: writeFn() case channeltypes.ErrNoOpMsg: - return &channeltypes.MsgRecvPacketResponse{}, nil // no-op + return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil default: return nil, sdkerrors.Wrap(err, "receive packet verification failed") } @@ -435,7 +435,7 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke ) }() - return &channeltypes.MsgRecvPacketResponse{}, nil + return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.SUCCESS}, nil } // Timeout defines a rpc handler method for MsgTimeout. @@ -473,7 +473,7 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c case nil: writeFn() case channeltypes.ErrNoOpMsg: - return &channeltypes.MsgTimeoutResponse{}, nil // no-op + return &channeltypes.MsgTimeoutResponse{Result: channeltypes.NOOP}, nil default: return nil, sdkerrors.Wrap(err, "timeout packet verification failed") } @@ -503,7 +503,7 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c ) }() - return &channeltypes.MsgTimeoutResponse{}, nil + return &channeltypes.MsgTimeoutResponse{Result: channeltypes.SUCCESS}, nil } // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. @@ -541,7 +541,7 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo case nil: writeFn() case channeltypes.ErrNoOpMsg: - return &channeltypes.MsgTimeoutOnCloseResponse{}, nil // no-op + return &channeltypes.MsgTimeoutOnCloseResponse{Result: channeltypes.NOOP}, nil default: return nil, sdkerrors.Wrap(err, "timeout on close packet verification failed") } @@ -574,7 +574,7 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo ) }() - return &channeltypes.MsgTimeoutOnCloseResponse{}, nil + return &channeltypes.MsgTimeoutOnCloseResponse{Result: channeltypes.SUCCESS}, nil } // Acknowledgement defines a rpc handler method for MsgAcknowledgement. @@ -612,7 +612,7 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn case nil: writeFn() case channeltypes.ErrNoOpMsg: - return &channeltypes.MsgAcknowledgementResponse{}, nil // no-op + return &channeltypes.MsgAcknowledgementResponse{Result: channeltypes.NOOP}, nil default: return nil, sdkerrors.Wrap(err, "acknowledge packet verification failed") } @@ -636,5 +636,5 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn ) }() - return &channeltypes.MsgAcknowledgementResponse{}, nil + return &channeltypes.MsgAcknowledgementResponse{Result: channeltypes.SUCCESS}, nil } diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index 7fc8f730e33..d4d6df1d5e9 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -42,6 +42,18 @@ service Msg { rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); } +// ResponseResultType defines the possible outcomes of the execution of a message +enum ResponseResultType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default zero value enumeration + RESPONSE_RESULT_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) + RESPONSE_RESULT_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; + // The message was executed successfully + RESPONSE_RESULT_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; +} + // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. message MsgChannelOpenInit { @@ -163,7 +175,11 @@ message MsgRecvPacket { } // MsgRecvPacketResponse defines the Msg/RecvPacket response type. -message MsgRecvPacketResponse {} +message MsgRecvPacketResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} // MsgTimeout receives timed-out packet message MsgTimeout { @@ -179,7 +195,11 @@ message MsgTimeout { } // MsgTimeoutResponse defines the Msg/Timeout response type. -message MsgTimeoutResponse {} +message MsgTimeoutResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} // MsgTimeoutOnClose timed-out packet upon counterparty channel closure. message MsgTimeoutOnClose { @@ -196,7 +216,11 @@ message MsgTimeoutOnClose { } // MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. -message MsgTimeoutOnCloseResponse {} +message MsgTimeoutOnCloseResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} // MsgAcknowledgement receives incoming IBC acknowledgement message MsgAcknowledgement { @@ -212,4 +236,8 @@ message MsgAcknowledgement { } // MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. -message MsgAcknowledgementResponse {} +message MsgAcknowledgementResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} diff --git a/testing/endpoint.go b/testing/endpoint.go index 5c2e2e33f4f..513fc8923cf 100644 --- a/testing/endpoint.go +++ b/testing/endpoint.go @@ -462,6 +462,36 @@ func (endpoint *Endpoint) TimeoutPacket(packet channeltypes.Packet) error { return endpoint.Chain.sendMsgs(timeoutMsg) } +// TimeoutOnClose sends a MsgTimeoutOnClose to the channel associated with the endpoint. +func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { + // get proof for timeout based on channel order + var packetKey []byte + + switch endpoint.ChannelConfig.Order { + case channeltypes.ORDERED: + packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) + case channeltypes.UNORDERED: + packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + default: + return fmt.Errorf("unsupported order type %s", endpoint.ChannelConfig.Order) + } + + proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey) + + channelKey := host.ChannelKey(packet.GetDestPort(), packet.GetDestChannel()) + proofClosed, _ := endpoint.Counterparty.QueryProof(channelKey) + + nextSeqRecv, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) + require.True(endpoint.Chain.T, found) + + timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnClose( + packet, nextSeqRecv, + proof, proofClosed, proofHeight, endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(timeoutOnCloseMsg) +} + // SetChannelClosed sets a channel state to CLOSED. func (endpoint *Endpoint) SetChannelClosed() error { channel := endpoint.GetChannel() diff --git a/testing/simapp/ante_handler.go b/testing/simapp/ante_handler.go index 8e3e1f069ec..04ffad13e2a 100644 --- a/testing/simapp/ante_handler.go +++ b/testing/simapp/ante_handler.go @@ -5,16 +5,15 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" - channelkeeper "github.com/cosmos/ibc-go/v3/modules/core/04-channel/keeper" ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" + "github.com/cosmos/ibc-go/v3/modules/core/keeper" ) -// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC -// channel keeper. +// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC keeper. type HandlerOptions struct { ante.HandlerOptions - IBCChannelkeeper channelkeeper.Keeper + IBCKeeper *keeper.Keeper } // NewAnteHandler creates a new ante handler @@ -49,7 +48,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), - ibcante.NewAnteDecorator(options.IBCChannelkeeper), + ibcante.NewAnteDecorator(options.IBCKeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/testing/simapp/app.go b/testing/simapp/app.go index 15add30faaf..ee148806852 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -503,7 +503,7 @@ func NewSimApp( FeegrantKeeper: app.FeeGrantKeeper, SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - IBCChannelkeeper: app.IBCKeeper.ChannelKeeper, + IBCKeeper: app.IBCKeeper, }, ) if err != nil {