From 11bf6ca3ce66ba1edfae4cd63c8b82197c9f7061 Mon Sep 17 00:00:00 2001 From: izyak Date: Tue, 21 Nov 2023 07:39:01 +0545 Subject: [PATCH 1/5] feat: update respective wasm client based on message sent from icon --- relayer/chains/icon/provider.go | 5 ++-- relayer/chains/penumbra/provider.go | 2 +- relayer/chains/wasm/provider.go | 2 +- relayer/processor/message_processor.go | 4 +++ relayer/processor/path_end_runtime.go | 35 +++++++++++++++++++++++--- relayer/processor/types_test.go | 2 +- relayer/provider/provider.go | 6 ++--- 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/relayer/chains/icon/provider.go b/relayer/chains/icon/provider.go index 45500d536..7b19e655f 100644 --- a/relayer/chains/icon/provider.go +++ b/relayer/chains/icon/provider.go @@ -181,8 +181,9 @@ func (h IconIBCHeader) ConsensusState() ibcexported.ConsensusState { } return &icon.ConsensusState{} } -func (h IconIBCHeader) ShouldUpdateWithZeroMessage() bool { - if h.Header != nil && h.Header.MessageCount == 0 { + +func (h IconIBCHeader) ShouldUpdateForProofContextChange() bool { + if h.Header != nil && h.Header.NextProofContext != nil { return true } return false diff --git a/relayer/chains/penumbra/provider.go b/relayer/chains/penumbra/provider.go index f57902aeb..0546c8473 100644 --- a/relayer/chains/penumbra/provider.go +++ b/relayer/chains/penumbra/provider.go @@ -142,7 +142,7 @@ func (h PenumbraIBCHeader) IsCompleteBlock() bool { return true } -func (h PenumbraIBCHeader) ShouldUpdateWithZeroMessage() bool { +func (h PenumbraIBCHeader) ShouldUpdateForProofContextChange() bool { return false } diff --git a/relayer/chains/wasm/provider.go b/relayer/chains/wasm/provider.go index c3ad74207..7d8eee058 100644 --- a/relayer/chains/wasm/provider.go +++ b/relayer/chains/wasm/provider.go @@ -182,7 +182,7 @@ func (a WasmIBCHeader) NextValidatorsHash() []byte { return a.SignedHeader.Header.NextValidatorsHash } -func (a WasmIBCHeader) ShouldUpdateWithZeroMessage() bool { +func (a WasmIBCHeader) ShouldUpdateForProofContextChange() bool { return false } diff --git a/relayer/processor/message_processor.go b/relayer/processor/message_processor.go index 44ff7a9ab..bd8d32bfc 100644 --- a/relayer/processor/message_processor.go +++ b/relayer/processor/message_processor.go @@ -276,6 +276,10 @@ func (mp *messageProcessor) assembleMsgUpdateClient(ctx context.Context, src, ds trustedConsensusHeight = clientConsensusHeight trustedNextValidatorsHash = header.NextValidatorsHash() } + if src.latestHeader == nil { + mp.log.Info("check for height error") + } + // fmt.Printf("Src latest Header in MP %v\n\n", src.latestHeader) if src.latestHeader.Height() == trustedConsensusHeight.RevisionHeight && !bytes.Equal(src.latestHeader.NextValidatorsHash(), trustedNextValidatorsHash) { diff --git a/relayer/processor/path_end_runtime.go b/relayer/processor/path_end_runtime.go index c134ab8bf..a9b26917d 100644 --- a/relayer/processor/path_end_runtime.go +++ b/relayer/processor/path_end_runtime.go @@ -391,10 +391,6 @@ func (pathEnd *pathEndRuntime) mergeCacheData(ctx context.Context, cancel func() pathEnd.latestHeader = d.LatestHeader pathEnd.clientState = d.ClientState - if pathEnd.chainProvider.Type() == common.IconModule && d.LatestHeader.IsCompleteBlock() { - pathEnd.BTPHeightQueue.Enqueue(BlockInfoHeight{Height: int64(d.LatestHeader.Height()), IsProcessing: false}) - } - terminate, err := pathEnd.checkForMisbehaviour(ctx, pathEnd.clientState, counterParty) if err != nil { pathEnd.log.Error( @@ -424,6 +420,37 @@ func (pathEnd *pathEndRuntime) mergeCacheData(ctx context.Context, cancel func() pathEnd.mergeMessageCache(d.IBCMessagesCache, counterpartyChainID, pathEnd.inSync && counterpartyInSync) // Merge incoming packet IBC messages into the backlog + if pathEnd.chainProvider.Type() == common.IconModule { + btpHeightKey := BlockInfoHeight{Height: int64(d.LatestHeader.Height()), IsProcessing: false} + if d.LatestHeader.ShouldUpdateForProofContextChange() { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + } else { + // nested for loop, but there won't be too many messages in a block. + if len(d.IBCMessagesCache.PacketFlow) > 0 { + for k, pmc := range d.IBCMessagesCache.PacketFlow { + ck := ChannelKey{ + ChannelID: k.ChannelID, + PortID: k.PortID, + CounterpartyChannelID: k.CounterpartyChannelID, + CounterpartyPortID: k.CounterpartyPortID, + } + + if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { + for event := range pmc { + // filter request timeout, send packet and write acknowledgement + if event == chantypes.EventTypeSendPacket || event == chantypes.EventTypeWriteAck || event == common.EventTimeoutRequest { + pathEnd.log.Info("This packet message is directed ", zap.String("from", pathEnd.chainProvider.ChainName()), zap.String("to", counterpartyChainID)) + if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + } + } + } + } + } + } + } + } + pathEnd.ibcHeaderCache.Merge(d.IBCHeaderCache) // Update latest IBC header state pathEnd.ibcHeaderCache.Prune(ibcHeadersToCache) // Only keep most recent IBC headers } diff --git a/relayer/processor/types_test.go b/relayer/processor/types_test.go index 5edb510fb..e6ea4a4ee 100644 --- a/relayer/processor/types_test.go +++ b/relayer/processor/types_test.go @@ -14,7 +14,7 @@ func (h mockIBCHeader) Height() uint64 { return 0 } func (h mockIBCHeader) ConsensusState() ibcexported.ConsensusState { return nil } func (h mockIBCHeader) NextValidatorsHash() []byte { return nil } func (h mockIBCHeader) IsCompleteBlock() bool { return true } -func (h mockIBCHeader) ShouldUpdateWithZeroMessage() bool { return false } +func (h mockIBCHeader) ShouldUpdateForProofContextChange() bool { return false } func TestIBCHeaderCachePrune(t *testing.T) { cache := make(processor.IBCHeaderCache) diff --git a/relayer/provider/provider.go b/relayer/provider/provider.go index 94eb8be35..7cad0cb44 100644 --- a/relayer/provider/provider.go +++ b/relayer/provider/provider.go @@ -63,8 +63,8 @@ type IBCHeader interface { Height() uint64 ConsensusState() ibcexported.ConsensusState NextValidatorsHash() []byte - IsCompleteBlock() bool //defined for IconIBCHeader - ShouldUpdateWithZeroMessage() bool //defined for IconIBCHeader + IsCompleteBlock() bool //defined for IconIBCHeader + ShouldUpdateForProofContextChange() bool //defined for IconIBCHeader } // ClientState holds the current state of a client from a single chain's perspective @@ -553,7 +553,7 @@ func (h TendermintIBCHeader) ConsensusState() ibcexported.ConsensusState { func (h TendermintIBCHeader) IsCompleteBlock() bool { return true } -func (h TendermintIBCHeader) ShouldUpdateWithZeroMessage() bool { +func (h TendermintIBCHeader) ShouldUpdateForProofContextChange() bool { return false } From a1550901195d7af017e6e21408ab67b9a3ff7784 Mon Sep 17 00:00:00 2001 From: izyak Date: Tue, 21 Nov 2023 07:42:48 +0545 Subject: [PATCH 2/5] chore: remove header nil log --- relayer/processor/message_processor.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/relayer/processor/message_processor.go b/relayer/processor/message_processor.go index bd8d32bfc..44ff7a9ab 100644 --- a/relayer/processor/message_processor.go +++ b/relayer/processor/message_processor.go @@ -276,10 +276,6 @@ func (mp *messageProcessor) assembleMsgUpdateClient(ctx context.Context, src, ds trustedConsensusHeight = clientConsensusHeight trustedNextValidatorsHash = header.NextValidatorsHash() } - if src.latestHeader == nil { - mp.log.Info("check for height error") - } - // fmt.Printf("Src latest Header in MP %v\n\n", src.latestHeader) if src.latestHeader.Height() == trustedConsensusHeight.RevisionHeight && !bytes.Equal(src.latestHeader.NextValidatorsHash(), trustedNextValidatorsHash) { From 981fb71e1e5f0469631f40caf72de4a981ecc548 Mon Sep 17 00:00:00 2001 From: izyak Date: Tue, 21 Nov 2023 10:21:27 +0545 Subject: [PATCH 3/5] chore: move btp updates to a function --- relayer/processor/path_end_runtime.go | 43 +++++++++++++++------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/relayer/processor/path_end_runtime.go b/relayer/processor/path_end_runtime.go index a9b26917d..832096a13 100644 --- a/relayer/processor/path_end_runtime.go +++ b/relayer/processor/path_end_runtime.go @@ -420,29 +420,37 @@ func (pathEnd *pathEndRuntime) mergeCacheData(ctx context.Context, cancel func() pathEnd.mergeMessageCache(d.IBCMessagesCache, counterpartyChainID, pathEnd.inSync && counterpartyInSync) // Merge incoming packet IBC messages into the backlog + pathEnd.updateBTPQueue(d, counterpartyChainID) + + pathEnd.ibcHeaderCache.Merge(d.IBCHeaderCache) // Update latest IBC header state + pathEnd.ibcHeaderCache.Prune(ibcHeadersToCache) // Only keep most recent IBC headers +} + +// handle update for icon btp blocks. +// When btp blocks are produced, forward them only to chain which the message is directed for. +// However, when proof context changes, update has to be sent +func (pathEnd *pathEndRuntime) updateBTPQueue(d ChainProcessorCacheData, counterpartyChainID string) { if pathEnd.chainProvider.Type() == common.IconModule { btpHeightKey := BlockInfoHeight{Height: int64(d.LatestHeader.Height()), IsProcessing: false} if d.LatestHeader.ShouldUpdateForProofContextChange() { pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) } else { // nested for loop, but there won't be too many messages in a block. - if len(d.IBCMessagesCache.PacketFlow) > 0 { - for k, pmc := range d.IBCMessagesCache.PacketFlow { - ck := ChannelKey{ - ChannelID: k.ChannelID, - PortID: k.PortID, - CounterpartyChannelID: k.CounterpartyChannelID, - CounterpartyPortID: k.CounterpartyPortID, - } + for k, pmc := range d.IBCMessagesCache.PacketFlow { + ck := ChannelKey{ + ChannelID: k.ChannelID, + PortID: k.PortID, + CounterpartyChannelID: k.CounterpartyChannelID, + CounterpartyPortID: k.CounterpartyPortID, + } - if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { - for event := range pmc { - // filter request timeout, send packet and write acknowledgement - if event == chantypes.EventTypeSendPacket || event == chantypes.EventTypeWriteAck || event == common.EventTimeoutRequest { - pathEnd.log.Info("This packet message is directed ", zap.String("from", pathEnd.chainProvider.ChainName()), zap.String("to", counterpartyChainID)) - if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { - pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) - } + if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { + for event := range pmc { + // filter request timeout, send packet and write acknowledgement + if event == chantypes.EventTypeSendPacket || event == chantypes.EventTypeWriteAck || event == common.EventTimeoutRequest { + pathEnd.log.Info("This packet message is directed ", zap.String("from", pathEnd.chainProvider.ChainId()), zap.String("to", counterpartyChainID)) + if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) } } } @@ -450,9 +458,6 @@ func (pathEnd *pathEndRuntime) mergeCacheData(ctx context.Context, cancel func() } } } - - pathEnd.ibcHeaderCache.Merge(d.IBCHeaderCache) // Update latest IBC header state - pathEnd.ibcHeaderCache.Prune(ibcHeadersToCache) // Only keep most recent IBC headers } // shouldSendPacketMessage determines if the packet flow message should be sent now. From dcac6e5214f2cead705534b330bd800be6974fda Mon Sep 17 00:00:00 2001 From: izyak Date: Tue, 21 Nov 2023 10:40:18 +0545 Subject: [PATCH 4/5] chore: formatting --- relayer/processor/path_end_runtime.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/relayer/processor/path_end_runtime.go b/relayer/processor/path_end_runtime.go index 832096a13..60742d0ff 100644 --- a/relayer/processor/path_end_runtime.go +++ b/relayer/processor/path_end_runtime.go @@ -447,8 +447,13 @@ func (pathEnd *pathEndRuntime) updateBTPQueue(d ChainProcessorCacheData, counter if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { for event := range pmc { // filter request timeout, send packet and write acknowledgement - if event == chantypes.EventTypeSendPacket || event == chantypes.EventTypeWriteAck || event == common.EventTimeoutRequest { - pathEnd.log.Info("This packet message is directed ", zap.String("from", pathEnd.chainProvider.ChainId()), zap.String("to", counterpartyChainID)) + if event == chantypes.EventTypeSendPacket || + event == chantypes.EventTypeWriteAck || + event == common.EventTimeoutRequest { + pathEnd.log.Info("This packet message is directed", + zap.String("from", pathEnd.chainProvider.ChainId()), + zap.String("to", counterpartyChainID), + ) if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) } From e05132e71dd911e6e4ca1ea77ebabf6f3afdf417 Mon Sep 17 00:00:00 2001 From: izyak Date: Thu, 23 Nov 2023 11:23:26 +0545 Subject: [PATCH 5/5] fix: handle update for handshake messages --- relayer/processor/path_end_runtime.go | 83 ++++++++++++++++++--------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/relayer/processor/path_end_runtime.go b/relayer/processor/path_end_runtime.go index 60742d0ff..8f8dd671b 100644 --- a/relayer/processor/path_end_runtime.go +++ b/relayer/processor/path_end_runtime.go @@ -430,35 +430,64 @@ func (pathEnd *pathEndRuntime) mergeCacheData(ctx context.Context, cancel func() // When btp blocks are produced, forward them only to chain which the message is directed for. // However, when proof context changes, update has to be sent func (pathEnd *pathEndRuntime) updateBTPQueue(d ChainProcessorCacheData, counterpartyChainID string) { - if pathEnd.chainProvider.Type() == common.IconModule { - btpHeightKey := BlockInfoHeight{Height: int64(d.LatestHeader.Height()), IsProcessing: false} - if d.LatestHeader.ShouldUpdateForProofContextChange() { - pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) - } else { - // nested for loop, but there won't be too many messages in a block. - for k, pmc := range d.IBCMessagesCache.PacketFlow { - ck := ChannelKey{ - ChannelID: k.ChannelID, - PortID: k.PortID, - CounterpartyChannelID: k.CounterpartyChannelID, - CounterpartyPortID: k.CounterpartyPortID, + if pathEnd.chainProvider.Type() != common.IconModule { + return + } + + btpHeightKey := BlockInfoHeight{Height: int64(d.LatestHeader.Height()), IsProcessing: false} + if d.LatestHeader.ShouldUpdateForProofContextChange() { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + return + } + + for k := range d.IBCMessagesCache.PacketFlow { + ck := ChannelKey{ + ChannelID: k.ChannelID, + PortID: k.PortID, + CounterpartyChannelID: k.CounterpartyChannelID, + CounterpartyPortID: k.CounterpartyPortID, + } + + if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { + + pathEnd.log.Info("This packet message is directed", + zap.String("to", counterpartyChainID), + zap.Uint64("height", d.LatestHeader.Height()), + ) + if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + return + } + } + } + + // handle for connection handshake + for _, v := range d.IBCMessagesCache.ConnectionHandshake { + for k := range v { + if k.ClientID == pathEnd.info.ClientID { + pathEnd.log.Info("This connection handshake message is directed", + zap.String("to", counterpartyChainID), + zap.Uint64("height", d.LatestHeader.Height()), + ) + if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + return } + } + } + } - if pathEnd.channelStateCache[ck] && d.LatestHeader.IsCompleteBlock() { - for event := range pmc { - // filter request timeout, send packet and write acknowledgement - if event == chantypes.EventTypeSendPacket || - event == chantypes.EventTypeWriteAck || - event == common.EventTimeoutRequest { - pathEnd.log.Info("This packet message is directed", - zap.String("from", pathEnd.chainProvider.ChainId()), - zap.String("to", counterpartyChainID), - ) - if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { - pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) - } - } - } + // handle for channel handshake + for _, v := range d.IBCMessagesCache.ChannelHandshake { + for _, x := range v { + if pathEnd.isRelevantConnection(x.ConnID) { + pathEnd.log.Info("This channel handshake message is directed", + zap.String("to", counterpartyChainID), + zap.Uint64("height", d.LatestHeader.Height()), + ) + if !pathEnd.BTPHeightQueue.ItemExist(btpHeightKey) { + pathEnd.BTPHeightQueue.Enqueue(btpHeightKey) + return } } }