diff --git a/relayer/chains/cosmos/multihop.go b/relayer/chains/cosmos/multihop.go index f6a459b97..46148133b 100644 --- a/relayer/chains/cosmos/multihop.go +++ b/relayer/chains/cosmos/multihop.go @@ -9,6 +9,7 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" "github.com/cosmos/ibc-go/v7/modules/core/multihop" + "github.com/cosmos/relayer/v2/relayer/provider" ) var _ multihop.Endpoint = (*endpoint)(nil) @@ -147,9 +148,9 @@ func (e endpoint) Counterparty() multihop.Endpoint { return e.counterparty } -func newEndpoint(provider *CosmosProvider, clientID, connectionID string) multihop.Endpoint { +func newEndpoint(provider provider.ChainProvider, clientID, connectionID string) multihop.Endpoint { return &endpoint{ - provider: provider, + provider: provider.(*CosmosProvider), clientID: clientID, connectionID: connectionID, } diff --git a/relayer/chains/cosmos/provider.go b/relayer/chains/cosmos/provider.go index 565712f14..b990f6dcd 100644 --- a/relayer/chains/cosmos/provider.go +++ b/relayer/chains/cosmos/provider.go @@ -3,6 +3,8 @@ package cosmos import ( "context" "fmt" + chantypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/multihop" "io" "os" "path" @@ -92,7 +94,7 @@ func (pc CosmosProviderConfig) NewProvider(log *zap.Logger, homepath string, deb // TODO: this is a bit of a hack, we should probably have a better way to inject modules Cdc: MakeCodec(pc.Modules, pc.ExtraCodecs), - queryProviders: map[string]*CosmosProvider{}, + chanPaths: map[string]*multihop.ChanPath{}, } return cp, nil @@ -123,12 +125,16 @@ type CosmosProvider struct { // for comet < v0.37, decode tm events as base64 cometLegacyEncoding bool - // queryProviders allows to query other chains for multi-hop proofs - queryProviders map[string]*CosmosProvider + // chanPaths tracks paths for multi-hop proofs + chanPaths map[string]*multihop.ChanPath } -func (cc *CosmosProvider) AddQueryProvider(chainID string, queryProvider provider.QueryProvider) { - cc.queryProviders[chainID] = queryProvider.(*CosmosProvider) +func (cc *CosmosProvider) AddChanPath(connectionHops []string, chanPath *multihop.ChanPath) { + cc.chanPaths[chantypes.FormatConnectionID(connectionHops)] = chanPath +} + +func (cc *CosmosProvider) GetChanPath(connectionHops []string) *multihop.ChanPath { + return cc.chanPaths[chantypes.FormatConnectionID(connectionHops)] } func (cc *CosmosProvider) ProviderConfig() provider.ProviderConfig { diff --git a/relayer/chains/cosmos/tx.go b/relayer/chains/cosmos/tx.go index ed6066f67..37cb0310c 100644 --- a/relayer/chains/cosmos/tx.go +++ b/relayer/chains/cosmos/tx.go @@ -537,11 +537,51 @@ func (cc *CosmosProvider) ValidatePacket(msgTransfer provider.PacketInfo, latest return nil } +func (cc *CosmosProvider) newProof(proof []byte, connectionHops []string) ([]byte, error) { + if len(connectionHops) == 0 { + return proof, nil + } + chanPath := cc.GetChanPath(connectionHops) + if chanPath == nil { + return nil, fmt.Errorf("unable to find channel path for connection hops: %v", connectionHops) + } + multihopProof, err := chanPath.GenerateProof(proof, nil, false) + if err != nil { + return nil, fmt.Errorf("error generating multihop proof: %w", err) + } + return multihopProof.Marshal() +} + +func (cc *CosmosProvider) newChannelProof(key []byte, height clienttypes.Height, version string, ordering chantypes.Order, + connectionHops []string) (provider.ChannelProof, error) { + proof, err := cc.newProof(key, connectionHops) + if err != nil { + return provider.ChannelProof{}, err + } + return provider.ChannelProof{ + Proof: proof, + ProofHeight: height, + Version: version, + Ordering: ordering, + }, nil +} + +func (cc *CosmosProvider) newPacketProof(key []byte, proofHeight clienttypes.Height, connectionHops []string) (provider.PacketProof, error) { + proof, err := cc.newProof(key, connectionHops) + if err != nil { + return provider.PacketProof{}, err + } + return provider.PacketProof{ + Proof: proof, + ProofHeight: proofHeight, + }, nil +} + func (cc *CosmosProvider) PacketCommitment( ctx context.Context, msgTransfer provider.PacketInfo, height uint64, - chainIDs, connectionHops []string, + connectionHops []string, ) (provider.PacketProof, error) { key := host.PacketCommitmentKey(msgTransfer.SourcePort, msgTransfer.SourceChannel, msgTransfer.Sequence) commitment, proof, proofHeight, err := cc.QueryTendermintProof(ctx, int64(height), key) @@ -552,13 +592,7 @@ func (cc *CosmosProvider) PacketCommitment( if len(commitment) == 0 { return provider.PacketProof{}, chantypes.ErrPacketCommitmentNotFound } - if proof, err = cc.generateMultihopProof(ctx, connectionHops, height, proof, chainIDs); err != nil { - return provider.PacketProof{}, err - } - return provider.PacketProof{ - Proof: proof, - ProofHeight: proofHeight, - }, nil + return cc.newPacketProof(proof, proofHeight, connectionHops) } func (cc *CosmosProvider) MsgRecvPacket( @@ -583,7 +617,7 @@ func (cc *CosmosProvider) PacketAcknowledgement( ctx context.Context, msgRecvPacket provider.PacketInfo, height uint64, - chainIDs, connectionHops []string, + connectionHops []string, ) (provider.PacketProof, error) { key := host.PacketAcknowledgementKey(msgRecvPacket.DestPort, msgRecvPacket.DestChannel, msgRecvPacket.Sequence) ack, proof, proofHeight, err := cc.QueryTendermintProof(ctx, int64(height), key) @@ -593,13 +627,7 @@ func (cc *CosmosProvider) PacketAcknowledgement( if len(ack) == 0 { return provider.PacketProof{}, chantypes.ErrInvalidAcknowledgement } - if proof, err = cc.generateMultihopProof(ctx, connectionHops, height, proof, chainIDs); err != nil { - return provider.PacketProof{}, err - } - return provider.PacketProof{ - Proof: proof, - ProofHeight: proofHeight, - }, nil + return cc.newPacketProof(proof, proofHeight, connectionHops) } func (cc *CosmosProvider) MsgAcknowledgement( @@ -625,20 +653,14 @@ func (cc *CosmosProvider) PacketReceipt( ctx context.Context, msgTransfer provider.PacketInfo, height uint64, - chainIDs, connectionHops []string, + connectionHops []string, ) (provider.PacketProof, error) { key := host.PacketReceiptKey(msgTransfer.DestPort, msgTransfer.DestChannel, msgTransfer.Sequence) _, proof, proofHeight, err := cc.QueryTendermintProof(ctx, int64(height), key) if err != nil { return provider.PacketProof{}, fmt.Errorf("error querying comet proof for packet receipt: %w", err) } - if proof, err = cc.generateMultihopProof(ctx, connectionHops, height, proof, chainIDs); err != nil { - return provider.PacketProof{}, err - } - return provider.PacketProof{ - Proof: proof, - ProofHeight: proofHeight, - }, nil + return cc.newPacketProof(proof, proofHeight, connectionHops) } // NextSeqRecv queries for the appropriate Tendermint proof required to prove the next expected packet sequence number @@ -648,20 +670,14 @@ func (cc *CosmosProvider) NextSeqRecv( ctx context.Context, msgTransfer provider.PacketInfo, height uint64, - chainIDs, connectionHops []string, + connectionHops []string, ) (provider.PacketProof, error) { key := host.NextSequenceRecvKey(msgTransfer.DestPort, msgTransfer.DestChannel) _, proof, proofHeight, err := cc.QueryTendermintProof(ctx, int64(height), key) if err != nil { return provider.PacketProof{}, fmt.Errorf("error querying comet proof for next sequence receive: %w", err) } - if proof, err = cc.generateMultihopProof(ctx, connectionHops, height, proof, chainIDs); err != nil { - return provider.PacketProof{}, err - } - return provider.PacketProof{ - Proof: proof, - ProofHeight: proofHeight, - }, nil + return cc.newPacketProof(proof, proofHeight, connectionHops) } func (cc *CosmosProvider) MsgTimeout(msgTransfer provider.PacketInfo, proof provider.PacketProof) (provider.RelayerMessage, error) { @@ -898,202 +914,18 @@ func getClientState( }, nil } -// generateMultihopProof generates proof of a key/value at the proofHeight on source chain. -func (cc *CosmosProvider) generateMultihopProof( - ctx context.Context, - connectionHops []string, - height uint64, - keyProof []byte, - chainIDs []string, -) ([]byte, error) { - if len(chainIDs) == 0 { - return keyProof, nil - } - multihopProof := chantypes.MsgMultihopProofs{ - KeyProof: &chantypes.MultihopProof{Proof: keyProof}, - } - chain0 := cc - chain1 := cc.queryProviders[chainIDs[0]] - - client01, err := getClientState(ctx, chain0, chain1, connectionHops[0], height) - - // Ensure that chain0's client state is update to date - // TODO: is it ok to exclude revision number? - if client01.dstHeight.GetRevisionHeight() < height { - return nil, fmt.Errorf("%s's client state is not up to date", cc.ChainId()) - } - - // Generate and assign consensus, clientState, and connection proofs - hopQueryProviders := make([]provider.QueryProvider, len(chainIDs)) - for i, chainID := range chainIDs { - var found bool - if hopQueryProviders[i], found = cc.queryProviders[chainID]; !found { - return nil, fmt.Errorf("query provider for chain %s not found", chainID) - } - } - var ccQueryProvider provider.QueryProvider - ccQueryProvider = cc - chains := append([]provider.QueryProvider{ccQueryProvider}, hopQueryProviders...) - // Normally they would be off by one (N chains, N-1 connections between then) but we don't have dst here, so they - // should match in length. - if len(chains) != len(connectionHops) { - return nil, fmt.Errorf("number of chains and connection IDs do not match") - } - if multihopProof.ConsensusProofs, multihopProof.ConnectionProofs, err = cc.generateConsensusAndConnectionProofs(ctx, - height, chains, connectionHops); err != nil { - return nil, err - } - return multihopProof.Marshal() -} - -func (cc *CosmosProvider) generateConsensusProof( - ctx context.Context, - srcChain provider.QueryProvider, - srcClientState, - dstClientState *clientState, -) (*chantypes.MultihopProof, error) { - // Consensus state of previous chain on current chain at consensusHeight which is the height of previous chain - // client state on current chain. - consensusHeight := srcClientState.dstHeight - proofHeight := dstClientState.dstHeight - - consensusStateResponse, err := srcChain.QueryClientConsensusState(ctx, srcClientState.dstChainHeight, - srcClientState.srcID, consensusHeight) - - key := host.FullConsensusStateKey(srcClientState.srcID, consensusHeight) - consensusKey, err := commitmenttypes.ApplyPrefix(srcClientState.dstPrefix, - commitmenttypes.NewMerklePath(string(key))) - if err != nil { - return nil, err - } - - // Proof of previous chain's consensus state at consensusHeight on currentChain at nextHeight. - // TODO: do we need proofHeight's revision number? - consensusProofResponse, err := srcChain.QueryClientConsensusState(ctx, - int64(proofHeight.GetRevisionHeight()), dstClientState.srcID, consensusHeight) - if err != nil { - return nil, err - } - - return &chantypes.MultihopProof{ - PrefixedKey: &consensusKey, - // TODO: do we need to marshal the value? - Value: consensusStateResponse.ConsensusState.Value, - Proof: consensusProofResponse.Proof, - }, nil -} - -func (cc *CosmosProvider) generateConnectionProof( - ctx context.Context, - srcChain provider.QueryProvider, - srcClientState, - dstClientState *clientState, - srcConnectionID string, -) (*chantypes.MultihopProof, error) { - // Proof of current chain's connection to previous Chain. - connectionHeight := srcClientState.dstHeight - proofHeight := dstClientState.dstHeight - // TODO: do we need revision number? - connectionEndResponse, err := srcChain.QueryConnection(ctx, int64(connectionHeight.GetRevisionHeight()), - srcConnectionID) - if err != nil { - return nil, err - } - key := host.ConnectionKey(srcConnectionID) - connectionKey, err := commitmenttypes.ApplyPrefix(srcClientState.dstPrefix, - commitmenttypes.NewMerklePath(string(key))) - if err != nil { - return nil, err - } - - // Query proof of the currentChain's connection with the previousChain at nextHeight (currentChain's state root - // height on nextChain). - // TODO: do we need revision number? - connectionProofResponse, err := srcChain.QueryConnection(ctx, int64(proofHeight.GetRevisionHeight()), - srcConnectionID) - if err != nil { - return nil, err - } - connectionEnd, err := connectionEndResponse.Connection.Marshal() - if err != nil { - return nil, err - } - return &chantypes.MultihopProof{ - PrefixedKey: &connectionKey, - Value: connectionEnd, - Proof: connectionProofResponse.Proof, - }, nil -} - -func (cc *CosmosProvider) generateConsensusAndConnectionProofs( - ctx context.Context, - height uint64, - chains []provider.QueryProvider, - hopConnectionIDs []string, -) ([]*chantypes.MultihopProof, []*chantypes.MultihopProof, error) { - consensusProofs := make([]*chantypes.MultihopProof, len(chains)-1) - connectionProofs := make([]*chantypes.MultihopProof, len(chains)-1) - // Iterate all but the last hop (i.e., exclude the last hop and dst) - for i := 0; i < len(chains)-1; i++ { - // Previous chains state root is on currentChain and is the source chain for i==0. - previousChain := chains[i] - // CurrentChain is where the proof is queried and generated. - currentChain := chains[i+1] - // NextChain holds the state root of the currentChain. - nextChain := chains[i+2] - - // Previous chain client state on current chain. - currentClientState, err := getClientState(ctx, previousChain, currentChain, hopConnectionIDs[i], height) - if err != nil { - return nil, nil, err - } - consensusAndConnectionHeight := currentClientState.dstHeight - - // Current chain state on next chain. - nextClientState, err := getClientState(ctx, currentChain, nextChain, hopConnectionIDs[i+1], - currentClientState.dstHeight.GetRevisionHeight()) - if err != nil { - return nil, nil, err - } - proofHeight := nextClientState.dstHeight - - if consensusAndConnectionHeight.LT(proofHeight) { - // TODO: update - return nil, nil, fmt.Errorf("consensus height is less than proof height") - } - - if consensusProofs[len(chains)-1-i], err = cc.generateConsensusProof(ctx, currentChain, currentClientState, - nextClientState); err != nil { - return nil, nil, err - } - if connectionProofs[len(chains)-1-i], err = cc.generateConnectionProof(ctx, currentChain, currentClientState, nextClientState, - hopConnectionIDs[i+1]); err != nil { - return nil, nil, err - } - } - return consensusProofs, nil, nil -} - func (cc *CosmosProvider) ChannelProof( ctx context.Context, msg provider.ChannelInfo, height uint64, - chainIDs []string, + connectionHops []string, ) (provider.ChannelProof, error) { channelRes, err := cc.QueryChannel(ctx, int64(height), msg.ChannelID, msg.PortID) if err != nil { return provider.ChannelProof{}, err } - proof, err := cc.generateMultihopProof(ctx, msg.ConnectionHops(), height, channelRes.Proof, chainIDs) - if err != nil { - return provider.ChannelProof{}, err - } - return provider.ChannelProof{ - Proof: proof, - ProofHeight: channelRes.ProofHeight, - Version: channelRes.Channel.Version, - Ordering: channelRes.Channel.Ordering, - }, nil + return cc.newChannelProof(channelRes.Proof, channelRes.ProofHeight, channelRes.Channel.Version, + channelRes.Channel.Ordering, msg.ConnectionHops()) } func (cc *CosmosProvider) MsgChannelOpenTry(msgOpenInit provider.ChannelInfo, proof provider.ChannelProof) (provider.RelayerMessage, error) { @@ -1302,12 +1134,12 @@ func (cc *CosmosProvider) RelayPacketFromSequence( var pp provider.PacketProof switch order { case chantypes.UNORDERED: - pp, err = cc.PacketReceipt(ctx, msgTransfer, dsth, nil, nil) + pp, err = cc.PacketReceipt(ctx, msgTransfer, dsth, nil) if err != nil { return nil, nil, err } case chantypes.ORDERED: - pp, err = cc.NextSeqRecv(ctx, msgTransfer, dsth, nil, nil) + pp, err = cc.NextSeqRecv(ctx, msgTransfer, dsth, nil) if err != nil { return nil, nil, err } @@ -1329,7 +1161,7 @@ func (cc *CosmosProvider) RelayPacketFromSequence( return nil, nil, err } } - pp, err := src.PacketCommitment(ctx, msgTransfer, srch, nil, nil) + pp, err := src.PacketCommitment(ctx, msgTransfer, srch, nil) if err != nil { return nil, nil, err } @@ -1350,7 +1182,7 @@ func (cc *CosmosProvider) AcknowledgementFromSequence(ctx context.Context, dst p return nil, err } - pp, err := dst.PacketAcknowledgement(ctx, msgRecvPacket, dsth, nil, nil) + pp, err := dst.PacketAcknowledgement(ctx, msgRecvPacket, dsth, nil) if err != nil { return nil, err } diff --git a/relayer/processor/message_processor.go b/relayer/processor/message_processor.go index b71b574df..b125964d2 100644 --- a/relayer/processor/message_processor.go +++ b/relayer/processor/message_processor.go @@ -109,7 +109,7 @@ func (mp *messageProcessor) processMessages( return err } } - mp.assembleMessages(ctx, messages, src, dst, hops) + mp.assembleMessages(ctx, messages, src, dst) return mp.trackAndSendMessages(ctx, src, dst, needsClientUpdate) } @@ -162,32 +162,46 @@ func (mp *messageProcessor) shouldUpdateClientNow(ctx context.Context, src, dst } // assembleMessages will assemble all messages in parallel. This typically involves proof queries for each. -func (mp *messageProcessor) assembleMessages(ctx context.Context, messages pathEndMessages, src, dst *pathEndRuntime, - hops []*pathEndRuntime) { +func (mp *messageProcessor) assembleMessages(ctx context.Context, messages pathEndMessages, src, dst *pathEndRuntime) { var wg sync.WaitGroup + // TODO: instantiate ChanPath on chain providers before getting here mp.connMsgs = make([]connectionMessageToTrack, len(messages.connectionMessages)) for i, msg := range messages.connectionMessages { wg.Add(1) - go mp.assembleMessage(ctx, msg, src, dst, hops, i, &wg) + go mp.assembleMessage(ctx, msg, src, dst, nil, i, &wg) } mp.chanMsgs = make([]channelMessageToTrack, len(messages.channelMessages)) for i, msg := range messages.channelMessages { wg.Add(1) - go mp.assembleMessage(ctx, msg, src, dst, hops, i, &wg) + var connectionHops []string + state := src.channelStateCache[ChannelInfoChannelKey(msg.info)] + if state != nil { + connectionHops = state.ConnectionHops + } + go mp.assembleMessage(ctx, msg, src, dst, connectionHops, i, &wg) } mp.clientICQMsgs = make([]clientICQMessageToTrack, len(messages.clientICQMessages)) for i, msg := range messages.clientICQMessages { wg.Add(1) - go mp.assembleMessage(ctx, msg, src, dst, hops, i, &wg) + go mp.assembleMessage(ctx, msg, src, dst, nil, i, &wg) } mp.pktMsgs = make([]packetMessageToTrack, len(messages.packetMessages)) for i, msg := range messages.packetMessages { wg.Add(1) - go mp.assembleMessage(ctx, msg, src, dst, hops, i, &wg) + var connectionHops []string + key, err := msg.channelKey() + if err != nil { + panic(err) + } + state := src.channelStateCache[key] + if state != nil { + connectionHops = state.ConnectionHops + } + go mp.assembleMessage(ctx, msg, src, dst, connectionHops, i, &wg) } wg.Wait() @@ -211,11 +225,11 @@ func (mp *messageProcessor) assembleMessage( ctx context.Context, msg ibcMessage, src, dst *pathEndRuntime, - hops []*pathEndRuntime, + connectionHops []string, i int, wg *sync.WaitGroup, ) { - assembled, err := msg.assemble(ctx, src, dst, hops) + assembled, err := msg.assemble(ctx, src, dst, connectionHops) mp.trackMessage(msg.tracker(assembled), i) wg.Done() if err != nil { diff --git a/relayer/processor/types_internal.go b/relayer/processor/types_internal.go index d27e8c277..db0cbac20 100644 --- a/relayer/processor/types_internal.go +++ b/relayer/processor/types_internal.go @@ -24,7 +24,7 @@ type pathEndMessages struct { type ibcMessage interface { // assemble executes the appropriate proof query function, // then, if successful, assembles the message for the destination. - assemble(ctx context.Context, src, dst *pathEndRuntime, hops []*pathEndRuntime) (provider.RelayerMessage, error) + assemble(ctx context.Context, src, dst *pathEndRuntime, connectionHops []string) (provider.RelayerMessage, error) // tracker creates a message tracker for message status tracker(assembled provider.RelayerMessage) messageToTrack @@ -47,9 +47,9 @@ type packetIBCMessage struct { // then, if successful, assembles the packet message for the destination. func (msg packetIBCMessage) assemble(ctx context.Context, src, dst *pathEndRuntime, - hops []*pathEndRuntime, + connectionHops []string, ) (provider.RelayerMessage, error) { - var packetProof func(context.Context, provider.PacketInfo, uint64, []string, []string) (provider.PacketProof, error) + var packetProof func(context.Context, provider.PacketInfo, uint64, []string) (provider.PacketProof, error) var assembleMessage func(provider.PacketInfo, provider.PacketProof) (provider.RelayerMessage, error) switch msg.eventType { case chantypes.EventTypeRecvPacket: @@ -81,19 +81,7 @@ func (msg packetIBCMessage) assemble(ctx context.Context, ctx, cancel := context.WithTimeout(ctx, packetProofQueryTimeout) defer cancel() - var proof provider.PacketProof - var err error - hopChainIDs := make([]string, len(hops)) - for i, hop := range hops { - hopChainIDs[i] = hop.chainProvider.ChainId() - src.chainProvider.AddQueryProvider(hop.chainProvider.ChainId(), hop.chainProvider) - } - channelKey, err := msg.channelKey() - if err != nil { - return nil, err - } - proof, err = packetProof(ctx, msg.info, src.latestBlock.Height, hopChainIDs, - src.channelStateCache.GetConnectionHops(channelKey)) + proof, err := packetProof(ctx, msg.info, src.latestBlock.Height, connectionHops) if err != nil { return nil, fmt.Errorf("error querying packet proof: %w", err) } @@ -151,7 +139,7 @@ type channelIBCMessage struct { func (msg channelIBCMessage) assemble( ctx context.Context, src, dst *pathEndRuntime, - hops []*pathEndRuntime, + connectionHops []string, ) (provider.RelayerMessage, error) { var chanProof func(context.Context, provider.ChannelInfo, uint64, []string) (provider.ChannelProof, error) var assembleMessage func(provider.ChannelInfo, provider.ChannelProof) (provider.RelayerMessage, error) @@ -180,12 +168,7 @@ func (msg channelIBCMessage) assemble( var proof provider.ChannelProof var err error if chanProof != nil { - hopChainIDs := make([]string, len(hops)) - for i, hop := range hops { - hopChainIDs[i] = hop.chainProvider.ChainId() - src.chainProvider.AddQueryProvider(hop.chainProvider.ChainId(), hop.chainProvider) - } - proof, err = chanProof(ctx, msg.info, src.latestBlock.Height, hopChainIDs) + proof, err = chanProof(ctx, msg.info, src.latestBlock.Height, connectionHops) if err != nil { return nil, fmt.Errorf("error querying channel proof: %w", err) } @@ -233,7 +216,7 @@ type connectionIBCMessage struct { func (msg connectionIBCMessage) assemble( ctx context.Context, src, dst *pathEndRuntime, - hops []*pathEndRuntime, + connectionHops []string, ) (provider.RelayerMessage, error) { var connProof func(context.Context, provider.ConnectionInfo, uint64) (provider.ConnectionProof, error) var assembleMessage func(provider.ConnectionInfo, provider.ConnectionProof) (provider.RelayerMessage, error) @@ -307,7 +290,7 @@ type clientICQMessage struct { func (msg clientICQMessage) assemble( ctx context.Context, src, dst *pathEndRuntime, - hops []*pathEndRuntime, + connectionHops []string, ) (provider.RelayerMessage, error) { ctx, cancel := context.WithTimeout(ctx, interchainQueryTimeout) defer cancel() diff --git a/relayer/provider/provider.go b/relayer/provider/provider.go index 1a4e7c902..ee8686309 100644 --- a/relayer/provider/provider.go +++ b/relayer/provider/provider.go @@ -3,6 +3,7 @@ package provider import ( "context" "fmt" + "github.com/cosmos/ibc-go/v7/modules/core/multihop" "time" "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -240,8 +241,11 @@ type ChainProvider interface { Init(ctx context.Context) error - // AddQueryProvider adds a query provider for another chain - AddQueryProvider(chainID string, queryProvider QueryProvider) + // AddChanPath adds multihop channel path to a destination chain + AddChanPath(connectionHops []string, chanPath *multihop.ChanPath) + + // GetChanPath gets multihop channel path to a destination chain + GetChanPath(connectionHops []string) *multihop.ChanPath // [Begin] Client IBC message assembly functions NewClientState(dstChainID string, dstIBCHeader IBCHeader, dstTrustingPeriod, dstUbdPeriod time.Duration, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool) (ibcexported.ClientState, error) @@ -264,18 +268,18 @@ type ChainProvider interface { // These functions query the proof of the packet state on the chain. // PacketCommitment queries for proof that a MsgTransfer has been committed on the chain. - PacketCommitment(ctx context.Context, msgTransfer PacketInfo, height uint64, chainIDs, connectionHops []string) (PacketProof, error) + PacketCommitment(ctx context.Context, msgTransfer PacketInfo, height uint64, connectionHops []string) (PacketProof, error) // PacketAcknowledgement queries for proof that a MsgRecvPacket has been committed on the chain. - PacketAcknowledgement(ctx context.Context, msgRecvPacket PacketInfo, height uint64, chainIDs, connectionHops []string) (PacketProof, error) + PacketAcknowledgement(ctx context.Context, msgRecvPacket PacketInfo, height uint64, connectionHops []string) (PacketProof, error) // PacketReceipt queries for proof that a MsgRecvPacket has not been committed to the chain. - PacketReceipt(ctx context.Context, msgTransfer PacketInfo, height uint64, chainIDs, connectionHops []string) (PacketProof, error) + PacketReceipt(ctx context.Context, msgTransfer PacketInfo, height uint64, connectionHops []string) (PacketProof, error) // NextSeqRecv queries for the appropriate proof required to prove the next expected packet sequence number // for a given counterparty channel. This is used in ORDERED channels to ensure packets are being delivered in the // exact same order as they were sent over the wire. - NextSeqRecv(ctx context.Context, msgTransfer PacketInfo, height uint64, chainIDs, connectionHops []string) (PacketProof, error) + NextSeqRecv(ctx context.Context, msgTransfer PacketInfo, height uint64, connectionHops []string) (PacketProof, error) // MsgTransfer constructs a MsgTransfer message ready to write to the chain. MsgTransfer(dstAddr string, amount sdk.Coin, info PacketInfo) (RelayerMessage, error) @@ -333,9 +337,8 @@ type ChainProvider interface { // [Begin] Channel handshake IBC message assembly - // ChannelProof queries for proof of a channel state. If the channel is multi-hop, the chainIDs are for the - // intermediate hops. - ChannelProof(ctx context.Context, msg ChannelInfo, height uint64, chainIDs []string) (ChannelProof, error) + // ChannelProof queries for proof of a channel state. + ChannelProof(ctx context.Context, msg ChannelInfo, height uint64, connectionHops []string) (ChannelProof, error) // MsgChannelOpenInit takes channel info and assembles a MsgChannelOpenInit message // ready to write to the chain. The channel proof is not needed here, but it needs