Skip to content

ICS04: some questions about function timeoutOnClose and timeoutPacket #968

Open
@michwqy

Description

@michwqy

Question 1

As ICS03, the connection can't be closed.

Once opened, connections cannot be closed and identifiers cannot be reallocated

But as ICS04, there are two comments in timeoutPacket and timeoutOnClose.

note: the connection may have been closed

It may be a mistake.

Question 2

I found a logical problem, but I'm not sure if it works in reality. (Some mistakes are possible but may not practical.)

As ICS04, A module can call sendPacket before a channel open.

function sendPacket(
  capability: CapabilityKey,
  sourcePort: Identifier,
  sourceChannel: Identifier,
  timeoutHeight: Height,
  timeoutTimestamp: uint64,
  data: bytes): uint64 {
    ...
    abortTransactionUnless(channel !== null)
    abortTransactionUnless(channel.state !== CLOSED)
    ...
  }

Assume the module successively calls chanOpenInit, sendPacket and chanCloseInit, which results that there is a in-flight packet and the closed channel.

The module can't call timeoutOnClose since there is no counterparty channel.

function timeoutOnClose(
  packet: Packet,
  proof: CommitmentProof,
  proofClosed: CommitmentProof,
  proofHeight: Height,
  nextSequenceRecv: Maybe<uint64>,
  relayer: string): Packet {
    ...
    expected = ChannelEnd{CLOSED, channel.order, channel.portIdentifier,
                          channel.channelIdentifier, channel.connectionHops.reverse(), channel.version}
    abortTransactionUnless(connection.verifyChannelState(
      proofHeight,
      proofClosed,
      channel.counterpartyPortIdentifier,
      channel.counterpartyChannelIdentifier,
      expected
    ))
    ...    
  }

I think it does not match what the timeoutOnClose is designed for and

Any in-flight packets can be timed-out as soon as a channel is closed

We might be able to use timeoutPacket to make the in-flight packet to be timeout.

It doesn't matter that it has some problems (As #965). It needs to call verifyNextSequenceRecv, verifyPacketReceiptAbsence and verifyPacketReceipt anyway.

function timeoutPacket(
  packet: OpaquePacket,
  proof: CommitmentProof,
  proofHeight: Height,
  nextSequenceRecv: Maybe<uint64>,
  relayer: string): Packet {
    ...
    abortTransactionUnless(packet.destChannel === channel.counterpartyChannelIdentifier)
    ...
    abortTransactionUnless(connection.verifyNextSequenceRecv(
          proofHeight,
          proof,
          packet.destPort,
          packet.destChannel,
          nextSequenceRecv
        ))
    ...
    abortTransactionUnless(connection.verifyPacketReceiptAbsence(
          proofHeight,
          proof,
          packet.destPort,
          packet.destChannel,
          packet.sequence
        ))
    ...
    abortTransactionUnless(connection.verifyPacketReceipt(
          proofHeight,
          proof,
          packet.destPort,
          packet.destChannel,
          packet.sequence
          TIMEOUT_RECEIPT,
        ))        
  }

I don't know if there functions work properly when channel.counterpartyChannelIdentifier is empty.

And in ibc-go, TimeoutPacket can't be called when channel is closed.

func (k Keeper) TimeoutPacket(
	ctx sdk.Context,
	packet exported.PacketI,
	proof []byte,
	proofHeight exported.Height,
	nextSequenceRecv uint64,
) error {
	if channel.State != types.OPEN {
		return errorsmod.Wrapf(
			types.ErrInvalidChannelState,
			"channel state is not OPEN (got %s)", channel.State.String(),
		)
	}    
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    questiontaoTransport, authentication, & ordering layer.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions