Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FlushStatus Checks to RecvPacket #3914

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a290fed
add check for not equal NOTINFLUSH for SendPacket
chatton Jun 21, 2023
adfc53e
added test cases
chatton Jun 21, 2023
31acbec
Merge branch '04-channel-upgrades' into cian/issue#3875-add-flush-sta…
chatton Jun 21, 2023
6a36bc5
adding test cases and conditional first pass
chatton Jun 21, 2023
40d9351
split out status flush check into separate conditional
chatton Jun 21, 2023
b182061
Merge branch 'cian/issue#3875-add-flush-status-check-in-sendpacket-' …
chatton Jun 21, 2023
79be234
refactoring to single if condition
chatton Jun 21, 2023
20da85f
Address feedback.
DimitrisJim Jun 23, 2023
b590bed
Tweak them tests.
DimitrisJim Jun 23, 2023
fb983cc
adding test cases and conditional first pass
chatton Jun 21, 2023
f8ac337
split out status flush check into separate conditional
chatton Jun 21, 2023
4f4ecf9
refactoring to single if condition
chatton Jun 21, 2023
cbdc846
Address feedback.
DimitrisJim Jun 23, 2023
9396ea4
Tweak them tests.
DimitrisJim Jun 23, 2023
4edd3b9
Don't set version for non-initiating chain.
DimitrisJim Jun 29, 2023
5ded370
Merge branch 'cian/issue#3876-add-flush-status-check-in-recvpacket-' …
charleenfei Jun 30, 2023
b8dce46
Merge branch '04-channel-upgrades' into cian/issue#3876-add-flush-sta…
charleenfei Jun 30, 2023
6f09439
update code+test
charleenfei Jun 30, 2023
aee4623
applied suggestion from PR feedback
chatton Jul 4, 2023
f047c40
added test cases to check individual or conditions
chatton Jul 4, 2023
919fa83
Merge branch '04-channel-upgrades' into cian/issue#3876-add-flush-sta…
chatton Jul 5, 2023
f146dc3
apply PR feedback about error messages
chatton Jul 5, 2023
3849847
Merge branch '04-channel-upgrades' into cian/issue#3876-add-flush-sta…
chatton Jul 5, 2023
fa273eb
Merge branch '04-channel-upgrades' into cian/issue#3876-add-flush-sta…
chatton Jul 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions modules/core/04-channel/keeper/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

"github.com/cosmos/ibc-go/v7/internal/collections"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
"github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
Expand Down Expand Up @@ -133,11 +134,16 @@ func (k Keeper) RecvPacket(
return errorsmod.Wrap(types.ErrChannelNotFound, packet.GetDestChannel())
}

if channel.State != types.OPEN {
return errorsmod.Wrapf(
types.ErrInvalidChannelState,
"channel state is not OPEN (got %s)", channel.State.String(),
)
if !collections.Contains(channel.State, []types.State{types.OPEN, types.TRYUPGRADE, types.ACKUPGRADE}) {
return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected channel state to be one of [%s, %s, %s], but got %s", types.OPEN.String(), types.TRYUPGRADE.String(), types.ACKUPGRADE.String(), channel.State.String())
}

// in the case of the channel being in TRYUPGRADE or ACKUPGRADE we need to ensure that the channel is not in flushing,
// and that the counterparty last sequence send is less than or equal to the packet sequence.
if counterpartyLastSequenceSend, found := k.GetCounterpartyLastPacketSequence(ctx, packet.GetDestPort(), packet.GetDestChannel()); found {
if channel.FlushStatus != types.FLUSHING || packet.GetSequence() > counterpartyLastSequenceSend {
return errorsmod.Wrapf(types.ErrInvalidFlushStatus, "expected channel flush status to be (%s) when counterparty last sequence send (%d) is set, failed to recv packet (%d)", types.FLUSHING, counterpartyLastSequenceSend, packet.GetSequence())
}
}

// Authenticate capability to ensure caller has authority to receive packet on this channel
Expand Down
81 changes: 81 additions & 0 deletions modules/core/04-channel/keeper/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,87 @@ func (suite *KeeperTestSuite) TestRecvPacket() {
// attempts to receive packet 2 without receiving packet 1
channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
}, true},
{
"success with channel in ACKUPGRADE: FLUSHING status",
func() {
suite.coordinator.Setup(path)
sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData)
suite.Require().NoError(err)
packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp)
channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)

// Move channel to correct state.
path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion

err = path.EndpointB.ChanUpgradeInit()
suite.Require().NoError(err)

err = path.EndpointA.ChanUpgradeTry()
suite.Require().NoError(err)

err = path.EndpointB.ChanUpgradeAck()
suite.Require().NoError(err)

channel := path.EndpointB.GetChannel()
channel.FlushStatus = types.FLUSHING
path.EndpointB.SetChannel(channel)

suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetCounterpartyLastPacketSequence(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sequence+1)
},
true,
},
{
"failure while upgrading channel, packet sequence > counterparty last send sequence",
func() {
suite.coordinator.Setup(path)
sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData)
suite.Require().NoError(err)
packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp)
channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)

channel := path.EndpointB.GetChannel()
channel.State = types.INITUPGRADE
channel.FlushStatus = types.FLUSHING
path.EndpointB.SetChannel(channel)

suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetCounterpartyLastPacketSequence(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sequence-1)
},
false,
},
{
"failure while upgrading channel, channel not flushing, packet sequence == counterparty last send sequence",
func() {
suite.coordinator.Setup(path)
sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData)
suite.Require().NoError(err)
packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp)
channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)

channel := path.EndpointB.GetChannel()
channel.FlushStatus = types.FLUSHCOMPLETE
path.EndpointB.SetChannel(channel)

suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetCounterpartyLastPacketSequence(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sequence)
},
false,
},
{
"failure while upgrading channel, channel flushing, packet sequence > counterparty last send sequence",
func() {
suite.coordinator.Setup(path)
sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData)
suite.Require().NoError(err)
packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp)
channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)

channel := path.EndpointB.GetChannel()
channel.FlushStatus = types.FLUSHING
path.EndpointB.SetChannel(channel)

suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetCounterpartyLastPacketSequence(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sequence-1)
},
false,
},
{"packet already relayed ORDERED channel (no-op)", func() {
expError = types.ErrNoOpMsg

Expand Down