Right now MsgChannelCloseInit
messages are unhandled in the relayer.
Do we observe it in the tendermint events? Do we need to handle it?
Implementing a MsgChannelCloseInit
/MsgChannelCloseConfirm
channel close flow would look something like this:
|
func (pp *PathProcessor) getUnrelayedChannelCloseMessagesAndToDelete(pathEndChannelCloseMessages pathEndChannelCloseMessages) pathEndChannelHandshakeResponse { |
|
res := pathEndChannelHandshakeResponse{ |
|
ToDeleteSrc: make(map[string][]ChannelKey), |
|
ToDeleteDst: make(map[string][]ChannelKey), |
|
} |
|
|
|
ChannelCloseLoop: |
|
for closeInitKey, closeInitMsg := range pathEndChannelCloseMessages.SrcMsgChannelCloseInit { |
|
fmt.Println("Looping through src msg channel close init") |
|
var foundCloseInit *provider.ChannelInfo |
|
for closeConfirmKey, closeConfirmMsg := range pathEndChannelCloseMessages.DstMsgChannelCloseConfirm { |
|
fmt.Println("Looping through dst msg channel close confirm") |
|
if closeInitKey == closeConfirmKey.Counterparty() { |
|
foundCloseInit = &closeConfirmMsg |
|
break |
|
} |
|
} |
|
if foundCloseInit == nil { |
|
// need to send close confirm to dst |
|
msgCloseConfirm := channelIBCMessage{ |
|
eventType: chantypes.EventTypeChannelCloseConfirm, |
|
info: closeInitMsg, |
|
} |
|
fmt.Println("Determining if messages should be sent") |
|
if pathEndChannelCloseMessages.Dst.shouldSendChannelMessage(msgCloseConfirm, pathEndChannelCloseMessages.Src) { |
|
res.DstMessages = append(res.DstMessages, msgCloseConfirm) |
|
} |
|
continue ChannelCloseLoop |
|
} |
|
|
|
// channel close packet flow is complete for this channel, remove all retention. |
|
res.ToDeleteSrc[chantypes.EventTypeChannelCloseInit] = append(res.ToDeleteSrc[chantypes.EventTypeChannelCloseInit], closeInitKey) |
|
res.ToDeleteDst[chantypes.EventTypeChannelCloseConfirm] = append(res.ToDeleteDst[chantypes.EventTypeChannelCloseConfirm], closeInitKey) |
|
} |
|
|
|
// now iterate through channel-close-complete messages and remove any leftover messages |
|
for closeConfirmKey := range pathEndChannelCloseMessages.DstMsgChannelCloseConfirm { |
|
res.ToDeleteSrc[chantypes.EventTypeChannelCloseInit] = append(res.ToDeleteSrc[chantypes.EventTypeChannelCloseInit], closeConfirmKey) |
|
res.ToDeleteDst[chantypes.EventTypeChannelCloseConfirm] = append(res.ToDeleteDst[chantypes.EventTypeChannelCloseConfirm], closeConfirmKey) |
|
} |
|
|
|
return res |
|
} |
|
pathEnd1ChannelCloseMessages := pathEndChannelCloseMessages{ |
|
Src: pp.pathEnd1, |
|
Dst: pp.pathEnd2, |
|
SrcMsgChannelCloseInit: pp.pathEnd1.messageCache.ChannelHandshake[chantypes.EventTypeChannelCloseInit], |
|
DstMsgChannelCloseConfirm: pp.pathEnd2.messageCache.ChannelHandshake[chantypes.EventTypeChannelCloseConfirm], |
|
} |
|
pathEnd2ChannelCloseMessages := pathEndChannelCloseMessages{ |
|
Src: pp.pathEnd2, |
|
Dst: pp.pathEnd1, |
|
SrcMsgChannelCloseInit: pp.pathEnd2.messageCache.ChannelHandshake[chantypes.EventTypeChannelCloseInit], |
|
DstMsgChannelCloseConfirm: pp.pathEnd1.messageCache.ChannelHandshake[chantypes.EventTypeChannelCloseConfirm], |
|
} |
|
pathEnd1ChannelCloseRes := pp.getUnrelayedChannelCloseMessagesAndToDelete(pathEnd1ChannelCloseMessages) |
|
pathEnd2ChannelCloseRes := pp.getUnrelayedChannelCloseMessagesAndToDelete(pathEnd2ChannelCloseMessages) |
|
tmpPathEnd1Msgs, tmpPathEnd2ChannelMessages := pp.channelMessagesToSend(pathEnd1ChannelCloseRes, pathEnd2ChannelCloseRes) |
|
pathEnd1ChannelMessages = append(pathEnd1ChannelMessages, tmpPathEnd1Msgs...) |
|
pathEnd2ChannelMessages = append(pathEnd2ChannelMessages, tmpPathEnd2ChannelMessages...) |
This code was written while @jtieri and I were working on channel closures until discovering that MsgChannelCloseInit
plays no part in the channel close flow involving MsgTimeout
on an ordered channel.