diff --git a/modules/apps/callbacks/v2/ibc_middleware_test.go b/modules/apps/callbacks/v2/ibc_middleware_test.go index 23455365fce..991fda4bf01 100644 --- a/modules/apps/callbacks/v2/ibc_middleware_test.go +++ b/modules/apps/callbacks/v2/ibc_middleware_test.go @@ -2,6 +2,7 @@ package v2_test import ( "fmt" + "time" errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" @@ -474,7 +475,7 @@ func (s *CallbacksTestSuite) TestOnTimeoutPacket() { // NOTE: we call send packet so transfer is setup with the correct logic to // succeed on timeout userGasLimit := 600_000 - timeoutTimestamp := uint64(s.chainB.GetContext().BlockTime().Unix()) + timeoutTimestamp := uint64(s.chainB.GetContext().BlockTime().Add(time.Second).Unix()) packetData = transfertypes.NewFungibleTokenPacketData( ibctesting.TestCoin.Denom, ibctesting.TestCoin.Amount.String(), diff --git a/modules/core/04-channel/v2/keeper/msg_server_test.go b/modules/core/04-channel/v2/keeper/msg_server_test.go index ad249547b65..d58a82c0d38 100644 --- a/modules/core/04-channel/v2/keeper/msg_server_test.go +++ b/modules/core/04-channel/v2/keeper/msg_server_test.go @@ -461,7 +461,9 @@ func (suite *KeeperTestSuite) TestMsgTimeout() { path.SetupV2() // Send packet from A to B - timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Unix()) + // make timeoutTimestamp 1 second more than sending chain time to ensure it passes SendPacket + // and times out successfully after update + timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Add(time.Second).Unix()) mockData := mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB) var err error diff --git a/modules/core/04-channel/v2/keeper/packet.go b/modules/core/04-channel/v2/keeper/packet.go index 34c10f94f82..ddf14733472 100644 --- a/modules/core/04-channel/v2/keeper/packet.go +++ b/modules/core/04-channel/v2/keeper/packet.go @@ -33,8 +33,8 @@ func (k *Keeper) sendPacket( // Note, the validate basic function in sendPacket does the timeoutTimestamp != 0 check and other stateless checks on the packet. // timeoutTimestamp must be greater than current block time timeout := time.Unix(int64(timeoutTimestamp), 0) - if timeout.Before(ctx.BlockTime()) { - return 0, "", errorsmod.Wrap(types.ErrTimeoutElapsed, "timeout is less than the current block timestamp") + if !timeout.After(ctx.BlockTime()) { + return 0, "", errorsmod.Wrapf(types.ErrTimeoutElapsed, "timeout is less than or equal the current block timestamp, %d <= %d", timeoutTimestamp, ctx.BlockTime().Unix()) } // timeoutTimestamp must be less than current block time + MaxTimeoutDelta diff --git a/modules/core/04-channel/v2/keeper/packet_test.go b/modules/core/04-channel/v2/keeper/packet_test.go index eb1bacc6e2a..de4c2ee3545 100644 --- a/modules/core/04-channel/v2/keeper/packet_test.go +++ b/modules/core/04-channel/v2/keeper/packet_test.go @@ -80,6 +80,12 @@ func (suite *KeeperTestSuite) TestSendPacket() { }, clienttypes.ErrInvalidHeight, }, + { + "timeout equal to sending chain blocktime", func() { + packet.TimeoutTimestamp = uint64(suite.chainA.GetContext().BlockTime().Unix()) + }, + types.ErrTimeoutElapsed, + }, { "timeout elapsed", func() { packet.TimeoutTimestamp = 1 @@ -563,7 +569,9 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { // create default packet with a timed out timestamp payload := mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB) - timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().Unix()) + // make timeoutTimestamp 1 second more than sending chain time to ensure it passes SendPacket + // and times out successfully after update + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().Add(time.Second).Unix()) // test cases may mutate timeout values packet = types.NewPacket(1, path.EndpointA.ClientID, path.EndpointB.ClientID, diff --git a/modules/core/ante/ante_test.go b/modules/core/ante/ante_test.go index b374847d182..29b3477d15e 100644 --- a/modules/core/ante/ante_test.go +++ b/modules/core/ante/ante_test.go @@ -170,7 +170,7 @@ func (suite *AnteTestSuite) createTimeoutMessage(isRedundant bool) sdk.Msg { // createTimeoutMessageV2 creates a V2 Timeout message for a packet sent from chain B to chain A. func (suite *AnteTestSuite) createTimeoutMessageV2(isRedundant bool) *channeltypesv2.MsgTimeout { - timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().Unix()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().Add(time.Second).Unix()) packet, err := suite.path.EndpointB.MsgSendPacket(timeoutTimestamp, mock.NewMockPayload(mock.ModuleNameA, mock.ModuleNameB)) suite.Require().NoError(err)