diff --git a/modules/core/04-channel/types/packet.go b/modules/core/04-channel/types/packet.go index b585f093e50..f3524990331 100644 --- a/modules/core/04-channel/types/packet.go +++ b/modules/core/04-channel/types/packet.go @@ -12,6 +12,8 @@ import ( "github.com/cosmos/ibc-go/v9/modules/core/exported" ) +const MaximumPayloadsSize = 262144 // 256 KiB. This is the maximum size of all payloads combined + // CommitPacket returns the packet commitment bytes. The commitment consists of: // sha256_hash(timeout_timestamp + timeout_height.RevisionNumber + timeout_height.RevisionHeight + sha256_hash(data)) // from a given packet. This results in a fixed length preimage. @@ -110,6 +112,10 @@ func (p Packet) ValidateBasic() error { return errorsmod.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") } + if len(p.Data) > MaximumPayloadsSize { + return errorsmod.Wrapf(ErrInvalidPacket, "packet data bytes cannot exceed %d bytes", MaximumPayloadsSize) + } + return nil } diff --git a/modules/core/04-channel/types/packet_test.go b/modules/core/04-channel/types/packet_test.go index 13bbde87598..60566bcae8c 100644 --- a/modules/core/04-channel/types/packet_test.go +++ b/modules/core/04-channel/types/packet_test.go @@ -60,6 +60,7 @@ func TestPacketValidateBasic(t *testing.T) { {types.NewPacket(validPacketData, 1, portid, chanid, invalidPort, cpchanid, timeoutHeight, timeoutTimestamp), errors.New("invalid destination port")}, {types.NewPacket(validPacketData, 1, portid, chanid, cpportid, invalidChannel, timeoutHeight, timeoutTimestamp), errors.New("invalid destination channel")}, {types.NewPacket(validPacketData, 1, portid, chanid, cpportid, cpchanid, disabledTimeout, 0), errors.New("packet timeout height and packet timeout timestamp cannot both be 0: invalid packet")}, + {types.NewPacket(make([]byte, types.MaximumPayloadsSize+1), 1, portid, chanid, cpportid, cpchanid, timeoutHeight, timeoutTimestamp), errors.New("packet data bytes cannot exceed 262144 bytes: invalid packet")}, } for _, tc := range testCases { diff --git a/modules/core/04-channel/v2/types/packet.go b/modules/core/04-channel/v2/types/packet.go index 21525033f2a..d3fd79d01c5 100644 --- a/modules/core/04-channel/v2/types/packet.go +++ b/modules/core/04-channel/v2/types/packet.go @@ -5,6 +5,7 @@ import ( errorsmod "cosmossdk.io/errors" + channeltypesv1 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ) @@ -36,10 +37,16 @@ func (p Packet) ValidateBasic() error { return errorsmod.Wrap(ErrInvalidPacket, "payloads must contain exactly one payload") } + totalPayloadsSize := 0 for _, pd := range p.Payloads { if err := pd.ValidateBasic(); err != nil { return errorsmod.Wrap(err, "invalid Payload") } + totalPayloadsSize += len(pd.Value) + } + + if totalPayloadsSize > channeltypesv1.MaximumPayloadsSize { + return errorsmod.Wrapf(ErrInvalidPacket, "packet data bytes cannot exceed %d bytes", channeltypesv1.MaximumPayloadsSize) } if err := host.ChannelIdentifierValidator(p.SourceClient); err != nil { diff --git a/modules/core/04-channel/v2/types/packet_test.go b/modules/core/04-channel/v2/types/packet_test.go index ec5d5776160..015ca83812f 100644 --- a/modules/core/04-channel/v2/types/packet_test.go +++ b/modules/core/04-channel/v2/types/packet_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" + channeltypesv1 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v9/testing" @@ -26,6 +27,22 @@ func TestValidateBasic(t *testing.T) { func() {}, nil, }, + { + "success, single payload just below MaxPayloadsSize", + func() { + packet.Payloads[0].Value = make([]byte, channeltypesv1.MaximumPayloadsSize-1) + }, + nil, + }, + { + "failure: invalid single payloads size", + func() { + // bytes that are larger than MaxPayloadsSize + packet.Payloads[0].Value = make([]byte, channeltypesv1.MaximumPayloadsSize+1) + }, + types.ErrInvalidPacket, + }, + // TODO: add test cases for multiple payloads when enabled (#7008) { "failure: payloads is nil", func() {